Asynchronous decoupling lets a producer send work without waiting for a consumer to be available. A message queue sits between them: producers add messages, and consumers read them later. Unlike a load balancer, which still requires a backend to handle a request at the time it arrives, the queue separates the two sides in time. section 14.0 section 14.2
A queue changes how an application handles work:
- It buffers peaks. Producers can submit messages faster than consumers process them; consumers catch up later. section 14.2
- It hides consumers from producers. Consumers can be stopped for maintenance while producers continue to submit messages. section 14.2
- It requires application changes. Producers must send messages, consumers must read them, and successful processing must be acknowledged to remove messages. Messages are retained for a limited time. section 14.2 section 14.3
On AWS, Simple Queue Service (SQS) provides the queue. Its at-least-once delivery means a consumer may receive a message twice, and messages are not guaranteed to arrive in order. Design the processing step with those limits in mind. Asynchronous processing also changes the user experience: a result may not be ready when the request is accepted. section 14.2 section 16.3
Process an uploaded image
A user creates a process and receives a unique ID, then uploads an image using that ID. A worker processes the image in the background. The user checks the ID for progress and sees the sepia-filtered image when processing finishes. This avoids making the image transformation part of one synchronous web request. section 16.3
Queue length can also drive capacity. In a URL-to-image application, a producer sends a URL and bookmark ID to SQS. Node.js workers on EC2 poll the queue, create screenshots, and store them in S3. A CloudWatch alarm monitors queue length and adjusts an Auto Scaling group as work rises or falls. This gives queued requests somewhere to wait during a peak, but it does not make results immediate. section 17.3.2
Listing 17.7 Monitoring the length of the SQS queue
# [...]
HighQueueAlarm:
Type: 'AWS::CloudWatch::Alarm'
Properties:
EvaluationPeriods: 1 #1
Statistic: Sum #2
Threshold: 5 #3
AlarmDescription: 'Alarm if queue length is higher than 5.'
Period: 300 #4
AlarmActions: #5
- !Ref ScalingUpPolicy
Namespace: 'AWS/SQS' #6
Dimensions: #7
- Name: QueueName
Value: !Sub '${SQSQueue.QueueName}'
ComparisonOperator: GreaterThanThreshold #8
MetricName: ApproximateNumberOfMessagesVisible #9
# [...]
The CloudWatch alarm configuration shows how an SQS queue-length metric can trigger a scaling policy when its threshold is exceeded. section 17.3.2
