介绍

:::tips 一个队列中的消息如果超时未消费,则会变为死信,超时分为两种情况:

  • 消息所在的队列设置了超时时间
  • 消息本身设置了超时时间

image.png

因此我们可以通过死信交换机+ttl来实现延时消息:

  • 给队列设置ttl属性,进入队列后超过ttl时间的消息变为死信
    • QueueBuilder.ttl(10000)
  • 给消息设置ttl属性,队列接收到消息超过ttl时间后变为死信【推荐】
    • MessageBuilder.setExpiration(“10000”)

当队列、消息都设置了ttl时,任意一个到期,消息都会成为死信 :::

定义消费者

:::tips 在消息消费者中的RabbitMqListener类中定义一个消费者,并声明绑定死信交换机和死信队列 :::

  1. //将这个类注册到Spring容器中
  2. @Component
  3. public class RabbitMqListener{
  4. //声明并绑定死信交换机和死信队列,同时监听死信队列中的消息
  5. @RabbitListener(bindings = @QueueBinding(
  6. value = @Queue(name = "dl.ttl.queue"),
  7. exchange = @Exchange(name = "dl.ttl.exchange"),
  8. key = "dl"
  9. ))
  10. public void listen(String msg){
  11. System.out.println("接收到延迟消息:", msg);
  12. }
  13. }

声明ttl队列(不推荐)

:::tips 在消息消费者的配置类中声明ttl队列与交换机,并声明绑定队列和交换机 :::

  1. @Configuration
  2. public class XxxConfig{
  3. //声明交换机
  4. @Bean
  5. public DirectExchange ttlExchange(){
  6. return new DirectExchange("ttl.direct");
  7. }
  8. //声明ttl队列
  9. @Bean
  10. public Queue ttlQueue(){
  11. return QueueBuilder.durable("ttl.queue") //指定队列名称
  12. .ttl(10000) //设置队列的超时时间,单位:毫秒
  13. .deadLetterExchange("dl.ttl.direct") //指定消息超时变成死信后发送给哪个死信交换机
  14. .deadLetterRoutingKey("dl") //指定死信交换机的路由key
  15. .build();
  16. }
  17. //声明绑定TTL队列和交换机
  18. @Bean
  19. public Binding ttlBinding(Queue ttlQueue, DirectExchange ttlExchange){
  20. return BindingBuilder.bind(ttlQueue).to(ttlExchange).with("ttl");
  21. }
  22. }

发送ttl消息(推荐)

:::tips 在消息生产者发送消息时设置ttl超时时间 :::

  1. @SpringBootTest
  2. public class MyTest{
  3. //注入RabbitTemplate对象
  4. @Autowired
  5. private RabbitTemplate rabbitTemplate;
  6. @Test
  7. public void test(){
  8. //指定交换机名称
  9. String exchangeName = "ttl.direct";
  10. //指定路由key
  11. String routingKey = "ttl";
  12. //构建消息
  13. Message message = MessageBuilder
  14. .withBody("这是一条测试消息".getBytes(StandardCharsets.UTF_8))
  15. .setDeliveryMode(MessageDeliveryMode.PERSISTENT) //设置消息持久化
  16. .setExpiration("5000") //设置消息超时时间,单位:毫秒
  17. .build();
  18. // 发送消息
  19. rabbitTemplate.convertAndSend(exchangeName, routingKey, message);
  20. }
  21. }