Producers and consumers
A producer is the part of a system that creates work. This shop takes an order and an email must go out. Instead of sending it itself, it puts a message, a note describing the job, on a queue and carries on.
A consumer, or worker, is a separate program that takes messages off the queue, oldest first, and does the job. Producer and consumer never talk directly, so either one can be slow, stopped or replaced: they are decoupled.
When the job is finished, the worker sends an acknowledgement, an ack. Only then does the queue delete its kept copy. If the ack never comes, the copy is still there, so a crash cannot lose the job.
A sale brings orders faster than the workers can send emails. The queue simply grows, and the workers keep their own steady pace. Each message goes to just one worker. Need more speed? Start more workers on the same queue.
When things fail
Worker 2 sends C's email and notes it, then crashes before its ack. The queue sees the connection drop and puts its kept copy of C back at the front. C will be delivered again: this is at-least-once delivery.
So a handler must be idempotent: running it twice has the same effect as running it once. Before sending, the worker checks a shared list of finished message ids. C is already there, so it skips the email and just acks.
Sending D fails. The worker does not ack: it rejects D, and the queue delivers it again. Most failures pass, like a mail server that is briefly down, so a retry, ideally after a growing pause, usually works. D keeps failing.
After a set number of tries, here 3, the queue gives up and moves the message to a dead-letter queue: a side queue for messages that cannot be handled. The rest keep flowing, and a person can inspect D, fix it and replay it.
Topics and brokers
Sometimes several services each need every message. With a topic, or publish/subscribe, every subscriber gets its own copy: the email service and the stock service both get order E. In a work queue, each message goes to one worker.
A message broker is a server that runs the queues. RabbitMQ deletes a message once it is acked. Kafka keeps an ordered log, and each consumer reads at its own position. Clouds offer managed ones, such as Amazon SQS and Google Pub/Sub.
What happens
;; step 1/10 · Put it on a queue # the shop (producer) q.put(msg) # message A: email order 1 # returns at once: the shop # does not wait for the email
The code card uses Python's standard queue.Queue, which works inside one program; there task_done() plays the part of the ack. With a broker over the network the calls differ (RabbitMQ's pika client calls ch.basic_ack, SQS calls DeleteMessage), but the loop has the same shape. The list of finished ids must live in shared storage such as a database, not in one worker's memory. A crash between sending and noting can still send twice, so careful systems write the id in the same transaction as the work, or pass it to the email service as an idempotency key.