CS6650 Building Scalable Distributed Systems
This assignment builds on assignment 1. Your client won’t change (unless it has a bug in it!). Your will implement processing logic in your server and post the result to a queue for subsequent processing.
In this assignment, you will implement the doPost() method in your servlet to:
Choose your own queue technology. RabbitMQ is an obvious one, AWS SQS another. Make sure you deploy RabbitMQ on its own EC2 instance. You can find various installation instructions here. We have tested the Ubuntu install and it works fine.
Your aim is to keep response times as low as possible. One free tier server will probably get pretty busy, so you will want to introduce load balancing.
You can set up AWS Elastic Load Balancing using either Application or Network load balancers. Enable load balancing with e.g. 4 free tier EC2 instances and see what effect this has on your performance.
A tutorial here should help.
Implement a plain old Java program to pull messages off the queue. This program simply receives messages from the queue and keeps a record of the individual lift rides for each skier in a hash map.
Your aim is to consume messages, ideally, as quickly as they are produced. This means your consumer will need to be multithreaded and your hash map thread safe.
Your aim here is to find the ‘best’ application configuration in terms of responsiveness to the client and managing queue size.
The questions you need to explore are:
You can use the RabbitMQ management console to track the number of messages in the queue, and producers and consumer rates.
Submit your work to Canvas Assignment 2 as a pdf document. The document should contain:
RabbitMQ and multithreading needs a few considerations. Read on ….
The basic abstraction that needs to be operated on by each thread is the channel. This means:
In your servlet (or equivalent if not using a servlet):
This should work fine, although the documentation say channels are meant to be long-lived and caution again churn.
So a better solution would be to create a channel pool that shares a bunch of pre-created channels (in .init()) to form a connection pool.
Roll your own is not too hard, but apache commons has a generic pool implementation that you could build on. The reading has an example of how to do this.
Another approach to implementing a channel pool would be to use a BlockingQueue. Not too tricky … give it a try!
On the consumer side, you probably want a multi-threaded consumer that just gets a message and writes to the hash map. In this case you can just create a channel per thread and all should be fine.
There’s an excellent write up that describes the complexities of multi-threaded RMQ clients here
And here’s some sample code you can work from.