Cheat SheetsRabbitMQMicroservices

Microservices — Cheat Sheet

RabbitMQ · 2 topics. Download the PDF or the Instagram carousel and share it.

Cheat Sheet · AiCanCode.org
Microservices
RabbitMQ2 topicsQuick revision reference
1

RabbitMQ in Microservices

RabbitMQ decouples microservices for asynchronous workflows, saga choreography, event notification, and integration events; use separate exchanges per service to avoid coupling.

  • Exchange-per-service: each service owns its exchange; consumers bind their own queues.
  • Publishing service does not know who consumes — loose coupling by design.
  • Saga choreography: services react to each other's events without a central coordinator.
  • Compensating transactions must be idempotent — messages may be delivered more than once.
  • convertSendAndReceive provides RPC (blocking request-reply) over AMQP via a temporary reply queue.
  • Always publish integration events AFTER the DB transaction commits (Transactional Outbox or @TransactionalEventListener).
Java — exchange-per-service ownership model
// order-service owns the "order-service" exchange
@Configuration // in order-service
public class OrderExchangeConfig {
    @Bean
    public TopicExchange orderServiceExchange() {
        return ExchangeBuilder.topicExchange("order-service")
            .durable(true).build();
    }
}

// inventory-service declares its own queue and binds to order-service exchange
@Configuration // in inventory-service
public class InventoryBindings {
    @Bean
    public TopicExchange orderServiceExchange() {
        // Reference the exchange owned by order-service
        return ExchangeBuilder.topicExchange("order-service")
            .durable(true).build();  // idempotent — OK to declare again
    }
    @Bean
    public Queue inventoryOrderQueue() {
        return QueueBuilder.durable("inventory-service.order-placed").build();
    }
    @Bean
    public Binding inventoryOrderBinding(Queue q, TopicExchange ex) {
        return BindingBuilder.bind(q).to(ex).with("order.placed");
    }
    @RabbitListener(queues = "inventory-service.order-placed")
    public void onOrderPlaced(OrderPlacedEvent event) {
        inventoryService.reserve(event.getItems());
    }
}
2

Error Handling Patterns

Combine retry (with back-off), DLX, and poison-message detection to build robust error handling; alert on DLQ growth and build replay tooling for production incidents.

  • Retry transient failures in-process (RetryInterceptorBuilder); dead-letter permanent failures for investigation.
  • RejectAndDontRequeueRecoverer sends nack + no-requeue after exhausting retries, triggering the DLX routing.
  • x-death headers on DLQ messages record the death count, reason (rejected/expired/maxlen), and originating queue.
  • Alert on DLQ depth growing — it means messages are failing consistently; investigate before the DLQ fills.
  • Poison messages loop forever without a death-count check; quarantine messages that die more than N times.
  • Build replay tooling before an incident — being able to re-publish DLQ messages after a bug fix is critical for recovery.
Java — RetryInterceptorBuilder with exponential back-off
@Configuration
public class ErrorHandlingConfig {

    @Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(
            ConnectionFactory connectionFactory,
            RabbitTemplate rabbitTemplate) {

        SimpleRabbitListenerContainerFactory factory =
            new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setAcknowledgeMode(AcknowledgeMode.AUTO);  // nack triggers retry

        // After 3 retries → dead-letter the message
        factory.setAdviceChain(
            RetryInterceptorBuilder.stateless()
                .maxAttempts(3)
                .backOffOptions(500, 2.0, 8000)  // 0.5s, 1s, 2s → DLQ
                .recoverer(new RejectAndDontRequeueRecoverer()) // nack + no requeue
                .build()
        );
        return factory;
    }
}

@RabbitListener(queues = "orders.queue")
public void processOrder(OrderEvent event) {
    // If this throws, Spring AMQP retries up to 3x before dead-lettering
    orderService.process(event);
}
Learn this free with Aria, your AI tutor → AiCanCode.org/learn/rabbitmq