Implementing Delayed Message Delivery with RabbitMQ and Spring Boot
This article explains how to implement delayed message delivery in RabbitMQ using the official delayed‑queue plugin and Spring Boot, covering configuration of exchanges, queues, bindings, message publishing with delay headers, and consumer handling, along with code examples and test results.
Delayed message delivery is widely used in e‑commerce scenarios such as automatic order confirmation after a fixed period, for example Taobao's seven‑day auto‑confirm and 12306's 30‑minute order timeout.
Traditional solutions like using Redis expiration, database polling, or JVM DelayQueue suffer from performance bottlenecks, memory pressure, or lack of persistence.
RabbitMQ provides a delayed‑queue plugin (available from version 3.6.x) that enables true delayed messaging without those drawbacks.
Configuration steps include defining a topic exchange that supports delayed messages, a durable queue, and a binding with a routing key.
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class MQConfig {
public static final String LAZY_EXCHANGE = "Ex.LazyExchange";
public static final String LAZY_QUEUE = "MQ.LazyQueue";
public static final String LAZY_KEY = "lazy.#";
@Bean
public TopicExchange lazyExchange() {
//Map
pros = new HashMap<>();
//pros.put("x-delayed-message", "topic");
TopicExchange exchange = new TopicExchange(LAZY_EXCHANGE, true, false, pros);
exchange.setDelayed(true);
return exchange;
}
@Bean
public Queue lazyQueue() {
return new Queue(LAZY_QUEUE, true);
}
@Bean
public Binding lazyBinding() {
return BindingBuilder.bind(lazyQueue()).to(lazyExchange()).with(LAZY_KEY);
}
}When sending a message, the delay is specified either by calling Message.setDelay(Integer) or by adding the x-delay header via a MessagePostProcessor .
import com.anqi.mq.config.MQConfig;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class MQSender {
@Autowired
private RabbitTemplate rabbitTemplate;
public void sendLazy(Object message) {
rabbitTemplate.setMandatory(true);
rabbitTemplate.setConfirmCallback(confirmCallback);
rabbitTemplate.setReturnCallback(returnCallback);
CorrelationData correlationData = new CorrelationData("12345678909" + new Date());
rabbitTemplate.convertAndSend(MQConfig.LAZY_EXCHANGE, "lazy.boot", message,
new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
message.getMessageProperties().setDelay(6000);
return message;
}
}, correlationData);
}
}The consumer listens on the lazy queue, acknowledges the message, and processes the payload after the configured delay.
import com.rabbitmq.client.Channel;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component
public class MQReceiver {
@RabbitListener(queues = "MQ.LazyQueue")
@RabbitHandler
public void onLazyMessage(Message msg, Channel channel) throws IOException {
long deliveryTag = msg.getMessageProperties().getDeliveryTag();
channel.basicAck(deliveryTag, true);
System.out.println("lazy receive " + new String(msg.getBody()));
}
}A JUnit test sends a simple string with a 6000 ms delay; the console shows the message being received after roughly six seconds, confirming the delayed‑queue functionality.
Architect
Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.