Project 2 - Scalable Applications
Overview
Writing applications in a scalable fashion is a central challenge to cloud computing. In this project, you will work in groups of 1-2 people to write an application for Amazon's cloud platform that takes advantage of their monitoring and management features to react dynamically to client load.
Part 1 - Project Idea
Rather than assigning a single target application, for this class you can choose what specific application you want to write. Your application must meet the following general requirements:
- Be a multi-user system that supports different login accounts
- Be a system that has distinct "clients" (which are stateless) operated by users, and "servers" (which share state amongst themselves) operated by the administrator
- Client software can either be web pages or native applications for Windows / OS X / Linux
- Server software must run on Amazon EC2 machines
- Store application "state" in the cloud, and not locally by clients. (Your client can have a temporary cache of some state for performance)
- Manage data in both text and binary formats
- Use load balancing to distribute requests to more than one server
- Dynamically spawn and kill servers based on current load to remain responsive to varying demand without wasting too much compute capacity.
- Be resilient to failures affecting a single server or network switch
- Provide a custom "health check" function on the server that interfaces with the Amazon monitoring system
- Note: See official documentation and an unofficial blog post and example code
In addition to the application requirements, you must provide and document two stand-alone tools:
- A stand-alone Chaos Monkey application so that administrators can test resilience to failure
- Note: Your Chaos Monkey must, at a minimum, be able to do two things.
- Randomly terminate EC2 nodes in your cluster to simulate hardware/software failure. The command-line API to AWS might make this job easy.
- Add sufficient latency to your database or S3 storage to simulate outage of these services. (This will have to be integrated into your server application code, but the Chaos Monkey app should be able to toggle this function on or off).
- For more information the "Chaos Monkey" idea, read Netflix's official blog post or some unofficial commentary on the subject.
- Note: A .NET-based Chaos Monkey is available for download (either an executable, or the source code if you want to make changes)
- A stand-alone Slashdot Monkey application so that administrators can test performance under varying traffic loads from 1-100 requests/sec.
- Note: If you have a website app, there are already tools available to load URLs repeatedly. Find one and use it! But, you probably can't generate 100 req/sec traffic from your laptop at home on DSL, so you'll need to investigate running an existing tool from inside Amazon EC2 instance(s) - i.e. run the tool in the cloud too!
The choice of what programming language(s), server/middleware app(s), and OS to use is up to you. We will have tutorials, however, that show one approach of many: Writing JavaServer Pages (JSP) in Eclipse and uploading the resulting "application" (a web site) to Amazon's Elastic Beanstalk management system to spawn/kill web servers dynamically based on current load.
Here are a few examples of projects that would meet the general requirements:
- iMessage clone to chat between different users ("chat" being both text and sharing pictures)
- Important feature: You can use a client on multiple devices, and see the same conversation history on each!
- Varient 1: The chat "client" is simply a web page that anyone can access
- Varient 2: The chat client is a standalone app for Windows, OS X, or Linux (your choice), that communicates with the server(s) over HTTP (which is easy to load balance on Amazon)
- GMail clone, including ability to include attachments with the message
- Simplification - Don't bother with real email sending/receiving ability. Sending simulated messages between users on your project is sufficient.
- Google docs clone
- Simplification - Don't write an AJAX interface yourself! Instead, integrate a free GUI HTML editors like TinyMCE. Then, all you have to worry about is taking the HTML string from the editor and saving it in your app.
- Dropbox clone
- No dedicated server component is needed here beyond Amazon services. You could write a Java client that communicates directly with Amazon S3/SimpleDB and performs the necessary file copies.
Note about project ideas: the focus of this projet is not creating fancy, Web 2.0 AJAX interfaces, or polished native clients for Mac/Windows/Linux, etc... You only need a functional user interface that allows you to demonstrate application operation. Any additional UI glitz is completely optional.
Submission Instructions:
- Create a mockup of your design in HTML that shows key pages or features with mock data already present. This mockup will not be functional! Bundle all your mockup files into a .zip or .tar.gz archive.
- Create a 1-page PDF idea document that names the group members, describes your idea, and describes what I am looking at when I view your mockup. In addition, describe what state will be stored in the cloud.
- Upload both items to Sakai.
Part 2 - Project Implementation
In this stage of the project, you will make the mockup functional. :-)
There are two deliverables for this part:
- A checkpoint in-class demonstration halfway through the time allotted for part 2 (see timeline below). At this checkpoint, you should demonstrate your work to date, as well as discuss any problems you have overcome and problems that are currently unresolved. Essentially, this is a normal project meeting, just a bit more visual.
- Time for demonstration: ~8 minutes, depending on the number of groups.
- A final in-class demonstration at the end of the time allottee for part 2. Here, you should show off your finished application, and explain how it works behind the scenes, including the Slashdot and Chaos Monkeys.
- Time for demonstration: ~15 minutes, depending on the number of groups.
Part 3 - Project Reporting
There are three deliverables for this part:
- Full source code to all components
- Installation and execution instructions - what steps would a classmate need to take to reproduce your work, including the Chaos Monkey and Slashdot Monkey tools? (For your instructions, it is safe to assume that the reader is already familiar with the tutorial presented in class. Thus, you can be brief for those "obvious" steps)
- A report documenting your completed project. This 2-3 page report should contain the following sections:
- Introduction - what does your application do?
- Algorithm details - how does your application transfer, store, and process data?
- Infrastructure used - what AWS services does your application rely on, and what do these services do?
- Fault tolerance - what failures will your application tolerate, and how does it do so? What failures will your application not currently tolerate? (There will be some!) What failures (according to the marketing literature) will the AWS services you application relies on tolerate? If you had an additional 6 weeks to focus purely on fault tolerance, how would you modify your application to tolerate these additional failure modes?
- Final thoughts and feedback - What was the easiest and hardest part of the project? What suggestions would you have if this project is repeated for future students?
- References - What sources did you use in building your project? Provide links to public source code, tutorials, discussion forums, mailing lists, etc..
Submission instructions: Upload the source code (in a compressed tarball or zip file, please), installation instructions (in PDF format), and the final report (in PDF format) to Sakai.
Timeline
Due Date | Working On | Deliverables at End |
---|---|---|
Mon, Mar 26th by 11:55pm |
Part 1: Brainstorming for idea and developing mockup |
1 page document describing idea + mockup |
Mon, Apr 9th (in class) | Part 2: Checkpoint and initial demo | In-class demo (of work to date) |
Mon, Apr 23rd (in class) | Part 2: Implementation complete! | In-class demo (of final system) |
Wed, Apr 25th by 11:55pm | Part 3: Report writeup and any final polishing |
Source code and final report |
Grading
- 10% - Project Idea Document and Mockup [Grading Rubric]
- 15% - Checkpoint / Initial Demonstation [Grading Rubric]
- 60% - Final Demonstation [Grading Rubric]
- 15% - Final Report and Source code [Grading Rubric]
FAQs
Q: How do I find the tag to use with the pre-written Chaos Monkey? (if I don't want to write my own that works in a different manner)
A: The Chaos Monkey randomly selects server(s) to kill. Because we all share a common parent account for this class, however, you can see your classmate's servers too. To avoid any mishaps, you need to be very specific about what servers the Chaos Monkey is allowed to choose from. Amazon EC2 servers can have an optional tag "name" and "value", and you can specify both of these options to the Chaos Monkey at the command line. (e.g., --name=THENAME --value=THEVALUE). You can manually set these tags/values by using the AWS web control panel. Even better, though, if you use Eclipse and Elastic Beanstalk together, Amazon already creates a tag for use by the load balancing service! All you need to do is find the right tag. Go to the AWS web control panel, pick the EC2 tab, and select one of your servers from the list. (Hint: The key_pair column is a good way to tell your servers apart from another student). Click on the Tags tab for your selected servers. You should see a name / value pair like this: aws:autoscaling:groupName / awseb-Shafer-Schedule-Env-CxBWJO6vQO. Use these when entering your Chaos Monkey command to unleash (just the right amount of) havoc.
Note that similar tags are also created by Elastic MapReduce, so you could use the Chaos Monkey to unleash havoc (and watch Hadoop MapReduce react) on your prior project as well.
Q: How do I upload a file to a JSP-based site?
A: The Apache Foundation has two libraries that are helpful in accomplishing this task: FileUpload and Commons IO (the base library). Tutorials are available on how to use these libraries in your Java code. Note, however, that this only allows you to transfer a file from the client (web browser) to the web server. Read the next question to see how to transfer the file to Amazon S3!
Q: How do I upload a file to Amazon S3?
A: The Amazon Java API includes an entire S3 client. Look for the PutObject() method. You can find example code for this client in Eclipse by creating a new AWS Java Project (not a AWS Java Web project). While these examples are written for integrating the Amazon API into standalone Java programs, much of this code is suitable for use in your website as well. For a website, you could use the FileUpload library from Apache to transfer the file from the client computer to the web server, and then use the Amazon API to transfer the file from the web server to S3! For maximum performance, be sure to not write the file to disk. (It even sounds slow to write a file to disk and turn around and read it right back!) Instead, get an InputStream from the FileUpload class (see their documentation for how to do this), and then pass that InputStream to the corresponding PutObject() method implemented in the Amazon API. The file data should stream through your web server without ever being written to disk.
Tip: The Amazon API is not good at setting the "Content-Type" metadata for uploaded files. It often defaults to application/octet-stream, which is just generic binary data. Your file gets uploaded fine, but when your web browser attempts to download it later, it doesn't know what to do with the data, and just saves it to disk. If you encounter this issue, you should use the API to manually set the file "MIME" type to the correct setting. For example, a .jpg image should be set to Image/jpeg. Then, when you download it, your web browser will display it! You can verify that the Content-Type data is set correctly by using the AWS S3 web browser. Navigate to your bucket/file, right-click and choose "Properties", and select the "Metadata" tab at the bottom panel.
Q: How do I download a file (e.g., an image) from Amazon S3?
A: You could do the reverse of the upload process by using the AWS API to pull the file from S3 to your server, and then push the file from the server to the client. But, that would be a lot of work! A better way is to take advantage of S3's "Website" feature. With this feature, you can stick plain HTML and image files in an S3 bucket and make them accessible via the web, no fancy API required. All you need to do is enable this feature, set the permissions correctly, and give the web browser the correct URL. Then, the web browser can retrieve the file (e.g. image) directly.
To enable the feature, load the AWS web console, choose the S3 tab, and right-click on the bucket that you want to hold your files. Choose "Properties" and select the "Website" tab at the bottom panel. Enable this feature, and set a dummy index file (which you don't particularly need). Note the http-style URL that is shown here! It should be something like http://<YOUR-BUCKET>.s3-website-us-east-1.amazonaws.com/. This is the URL that works for anonymous HTTP users. Any other URL you see elsewhere in the S3 browser uses https (s=secure) and only works for authenticated users, like your classmates! When you use this URL, just add in the filename at the end.
After enabling the website feature, you need to set a bucket-wide permission to allow anonymous access. Choose the "Permissions" tab and select "Edit Bucket Policy". Paste in the following policy obtained from the document Hosting Websites on Amazon S3. Don't forget to use the correct bucket name here!
{
"Version":"2008-10-17",
"Statement":[{
"Sid":"PublicReadForGetBucketObjects",
"Effect":"Allow",
"Principal": {
"AWS": "*"
},
"Action":["s3:GetObject"],
"Resource":["arn:aws:s3:::YOUR-BUCKET-NAME-HERE/*"
]
}
]
}"
Bucket Policy from Permissions Required for Website Access
References
- Tutorial #1 - Elastic Beanstalk Demo ("Travel Log")
- Tutorial #2 - Elastic Beanstalk Demo ("Web App from Scratch")
- Amazon Developer Tools (Command-line and Eclipse)
- Amazon Java API documentation (for all products)
- Amazon SimpleDB
- Product overview
- Developer documentation
- Limits and restrictions (note the 1024 byte data limit!)
- Amazon Elastic Beanstalk "Health Check" Function