related information
What is the delay queue
Messages in the queue after waiting for a specified time, consumers will be able to consume.
Scenarios
- Mall system, after half an hour under a single non-payment, the order is automatically canceled
Method to realize
RabbitMQ itself does not directly support the queuing delay, but by the survival time and the dead letter queue control message, can simulate the effect of a delay queue.
RabbitMQ survival time control message in two ways:
- Setting queue attributes (x-message-ttl), all the messages in the queue have the same expiration time
- Set message properties (expiration), have separate expiration time
On the dead letter queue can refer https://gitee.com/gongm_24/spring-boot-tutorial/tree/master/chapter18
aims
Integration Spring boot provided spring-boot-starter-amqp
to achieve delayed queue
Steps
Add dependent
The introduction of Spring Boot Starter parent project
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
</parent>
Add spring-boot-starter-amqp
dependence
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
After adding the following overall dependence
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Coding (transmitter)
Configuration
spring:
rabbitmq:
host: 127.0.0.1
port: 5672
username: admin
password: admin
Defining the Queue
Define a test queue TestDeadQueue, and configure the dead letter queue for the queue,
the method is configured in a statement queue when adding parameters x-dead-letter-exchange
and x-dead-letter-routing-key
,
in fact, when the consumer fails, the message is sent using the exchange and routing to the designated queue
@Configuration
public class DeadConfig {
@Bean
public Queue testDelayQueue() {
Map<String, Object> params = new HashMap<>();
params.put("x-dead-letter-exchange", "DeadExchange");
params.put("x-dead-letter-routing-key", "DeadRouting");
// 如果设置,则队列中所有消息的过期时间都是 5 秒,如果希望在每个消息中进行单独设置,则不能设置
params.put("x-message-ttl", 5000);
return new Queue("TestDelayQueue",true, false, false, params);
}
@Bean
DirectExchange testDelayExchange() {
return new DirectExchange("TestDelayExchange");
}
@Bean
Binding bindingTestDelayQueue() {
return BindingBuilder.bind(testDelayQueue()).to(testDelayExchange()).with("TestDelayRouting");
}
@Bean
public Queue deadQueue() {
return new Queue("DeadQueue",true);
}
@Bean
DirectExchange deadExchange() {
return new DirectExchange("DeadExchange");
}
@Bean
Binding bindingDeadQueue() {
return BindingBuilder.bind(deadQueue()).to(deadExchange()).with("DeadRouting");
}
}
Send test
@RunWith(SpringRunner.class)
@WebAppConfiguration
@SpringBootTest(classes = SenderApplication.class)
public class MqTest {
@Autowired
private RabbitTemplate rabbitTemplate;
// 队列设置了过期时间
@Test
public void testDelayQueue() throws Exception {
String msgId = String.valueOf(UUID.randomUUID());
String sendTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
Map<String,Object> map = new HashMap<>(4);
map.put("msgId", msgId);
map.put("msgData", "test delay queue");
map.put("sendTime", sendTime);
rabbitTemplate.convertAndSend("TestDelayExchange", "TestDelayRouting", map);
}
// 对消息设置过期时间,队列不用设置过期时间
@Test
public void testDelayQueueWithMessage() throws Exception {
String msgId = String.valueOf(UUID.randomUUID());
String sendTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
Map<String,Object> map = new HashMap<>(4);
map.put("msgId", msgId);
map.put("msgData", "test dead letter queue");
map.put("sendTime", sendTime);
rabbitTemplate.convertAndSend("TestDelayExchange", "TestDelayRouting", map, msg -> {
msg.getMessageProperties().setExpiration("5000");
return msg;
});
}
}
Source Address
Source chapter: https://gitee.com/gongm_24/spring-boot-tutorial.git
Conclusion
To sum up the life cycle of delayed messages: