As part of a service oriented infrastructure there comes a need to coordinate work between services. AWS provides a couple of services which allow for application components to communicate with each other and their users/administrators in a decoupled fashion.
The Simple Queue Service (SQS) is a mechanism for an applications producers to distribute work to their consumers in a scalable, reliable and fault tolerant way. The basic lifecycle in SQS is as follows:
- A queue is created
- Producers send arbitrary text messages into the queue
- Consumers are constantly listing the messages in a queue and when one is available they “check out” the work by reading the message
- Once the message is read a timer kicks that makes the message unreadable by other consumers for a certain period of time (called the visibility timeout).
- The consumer can then perform the necessary task described by the message and then delete the message from the queue
- If the consumer does not complete the task in time or fails for some other reason the message is made visible again in the queue and picked up by another consumer
One simple example of using this service would be for a Web application front end to take image conversion orders from a user and then throw the image conversion task into a queue that can then be serviced by a fleet of worker nodes that do the actual image processing (ie the compute heavy portion).
The Simple Notification Service (SNS) is a service that allows for the coordination of messages that have one or more recipient subscribing endpoints. In this service users create a topic and then other services and users can subscribe to the topic in order to receive notifications about its goings on. In this model the sender of the message does not have to know where messages are actually being sent but rather that all subscribers (ie people/apps who need the message) will receive the message in the form that they have requested. Subscriptions to topics can be made through various transport mechanisms:
By publishing a message to a topic with multiple subscribers you can ensure that both applications and the people managing them are all on the same page.
Eucalyptus currently does not implement SQS and SNS but the folks over at Comcast have created an incredibly useful open source project that mirrors the APIs with absolutely incredible fidelity. Not only did they ensure that their API coverage was accurate and useful but they built the application stack on top of Cassandra and Redis making it not only horizontally scalable but extremely performant to boot. For more information: Comcast CMB.
Running CMB in your Eucalyptus cloud
In order to simplify the process of installing and bootstrapping CMB, I have created an image that you can install on your cloud with all the requisite services in place. All instructions here should be performed from your Eucalyptus CLC with your admin credentials sourced.
- Download the image and decompress it
- curl http://eucalyptus-images.s3.amazonaws.com/public/cmb.raw.xz > cmb.raw.xz
- xz -d cmb.raw.xz
- Install the image
- euca-install-image –virt hvm -i cmb.raw -r x86_64 -b CMB -n CMB
- Launch the image
- euca-run-instance -k <my-keypair> <emi-from-step-2>
- Once the image is launched login to the admin portal to create your first user and get your credentials
- Goto http://<instance-public-ip>:6059/webui
- Login with: cns_internal/cns_internal
- Create a new user
- Take note of the Access and Secret keys for your new users
- Start using your new services with your favorite SDK
Example: Interacting with SQS using Boto
In the example below swap change the following variables to fit your environment:
- cmb_host – Hostname or IP of your CMB server
- access_key – Taken from step 4D above
- secret_key – Taken from step 4D above
#!/usr/bin/python from boto.sqs.regioninfo import SQSRegionInfo from boto.sqs.connection import SQSConnection cmb_host = 'instance-ip' access_key = 'your-access-key-from-step-4D' secret_key = 'your-secret-key-from-step-4D' cmb_sqs_port = 6059 sqs_region = SQSRegionInfo(endpoint=cmb_host, name='home') cmb_sqs = SQSConnection(aws_access_key_id=access_key, aws_secret_access_key=secret_key, region=sqs_region, is_secure=False, port=cmb_sqs_port) queue = cmb_sqs.create_queue('test') msg = queue.new_message('Hello World') queue.write(msg) all_queues = cmb_sqs.get_all_queues() print 'Current queues: ' + str(all_queues) for queue in all_queues: print 'Messages in queue: ' + str([msg.get_body() for msg in queue.get_messages()])