Working with Message Queues

1. Understanding Message Queue Patterns

PatternDescription
Point-to-pointOne producer, one consumer per msg (queue)
Pub/SubOne producer, many subscribers (topic/fanout)
Competing consumersMany workers share one queue
Request-replyReply queue + correlation id
RoutingTopic/header-based routing (RabbitMQ exchanges)

2. Implementing Producer-Consumer Pattern

Example: Kafka producer/consumer

// Producer
KafkaProducer<String, String> p = new KafkaProducer<>(props);
p.send(new ProducerRecord<>("orders", order.id, json));

// Consumer
KafkaConsumer<String, String> c = new KafkaConsumer<>(props);
c.subscribe(List.of("orders"));
while (true) {
    ConsumerRecords<String, String> recs = c.poll(Duration.ofMillis(500));
    for (var r : recs) handle(r);
    c.commitSync();
}

3. Implementing Message Acknowledgments

ModeSemantics
Auto-ackAcked on receive; risk of loss
Manual ack after processAt-least-once
Negative ack (nack)Reject + requeue / DLQ
Cumulative ackSingle ack covers offset range (Kafka)

4. Implementing Exactly-Once Semantics

MechanismSystem
Idempotent producer + transactionsKafka EOS (read-process-write)
Dedup at consumer (idempotency key)App layer
Two-phase commit with sinkFlink, Beam
Outbox patternDB tx writes msg + state
Warning: Pure exactly-once across boundaries is impossible (Two Generals); achieve "effectively once" via idempotency + dedup.

5. Handling Message Ordering Guarantees

GuaranteeSystem
Per-partition FIFOKafka, Kinesis
Per-queue FIFOSQS FIFO, Azure Service Bus sessions
Group orderingRabbitMQ single consumer; partition by key
Global orderingSingle partition (low throughput)

6. Implementing Dead Letter Queues

TriggerAction
Max retries exceededMove to DLQ
TTL expiredMove to DLQ
Queue length limitDrop or DLQ
Operator actionInspect, replay, or discard
AlertsMonitor DLQ depth as SLI

7. Implementing Message Expiration (TTL)

ScopeMechanism
Per-message TTLHeader (RabbitMQ expiration)
Per-queue TTLDefault for all in queue
Topic retentionKafka retention.ms
SQSVisibility timeout + 14-day max

8. Implementing Priority Queues

ApproachDetail
Priority fieldRabbitMQ x-max-priority
Multiple queues per levelWorkers poll high → low
Weighted fair queueRound-robin with weights

9. Handling Poison Messages

StepAction
DetectCounter on retries; consistent failure
QuarantineMove to DLQ after threshold
AlertEngineer investigates payload
ReplayAfter fix, re-enqueue from DLQ

10. Implementing Message Batching

KnobEffect
Batch sizeBigger = better throughput, higher latency
Linger timeWait to fill batch (Kafka linger.ms)
Compressiongzip, snappy, lz4, zstd — applied per batch
Trade-offThroughput ↑, end-to-end latency ↑

11. Understanding Message Broker Architectures

BrokerArchitectureBest For
KafkaDistributed log, partitionedHigh throughput, replay
RabbitMQSmart broker, routingComplex routing, low-mid scale
NATS / JetStreamLightweight pub/subMicroservices, IoT
PulsarSegmented log + tiered storageMulti-tenant, geo-replication
SQS / Pub/Sub / EventBridgeManaged, serverlessCloud-native, no ops
Redis StreamsIn-memory logLow-latency, smaller scale