介绍
:::tips 一个队列中的消息如果超时未消费,则会变为死信,超时分为两种情况:
- 消息所在的队列设置了超时时间
 - 消息本身设置了超时时间
 

因此我们可以通过死信交换机+ttl来实现延时消息:
- 给队列设置ttl属性,进入队列后超过ttl时间的消息变为死信
- QueueBuilder.ttl(10000)
 
 - 给消息设置ttl属性,队列接收到消息超过ttl时间后变为死信【推荐】
- MessageBuilder.setExpiration(“10000”)
 
 
当队列、消息都设置了ttl时,任意一个到期,消息都会成为死信 :::
定义消费者
:::tips 在消息消费者中的RabbitMqListener类中定义一个消费者,并声明绑定死信交换机和死信队列 :::
//将这个类注册到Spring容器中@Componentpublic class RabbitMqListener{//声明并绑定死信交换机和死信队列,同时监听死信队列中的消息@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "dl.ttl.queue"),exchange = @Exchange(name = "dl.ttl.exchange"),key = "dl"))public void listen(String msg){System.out.println("接收到延迟消息:", msg);}}
声明ttl队列(不推荐)
:::tips 在消息消费者的配置类中声明ttl队列与交换机,并声明绑定队列和交换机 :::
@Configurationpublic class XxxConfig{//声明交换机@Beanpublic DirectExchange ttlExchange(){return new DirectExchange("ttl.direct");}//声明ttl队列@Beanpublic Queue ttlQueue(){return QueueBuilder.durable("ttl.queue") //指定队列名称.ttl(10000) //设置队列的超时时间,单位:毫秒.deadLetterExchange("dl.ttl.direct") //指定消息超时变成死信后发送给哪个死信交换机.deadLetterRoutingKey("dl") //指定死信交换机的路由key.build();}//声明绑定TTL队列和交换机@Beanpublic Binding ttlBinding(Queue ttlQueue, DirectExchange ttlExchange){return BindingBuilder.bind(ttlQueue).to(ttlExchange).with("ttl");}}
发送ttl消息(推荐)
:::tips 在消息生产者发送消息时设置ttl超时时间 :::
@SpringBootTestpublic class MyTest{//注入RabbitTemplate对象@Autowiredprivate RabbitTemplate rabbitTemplate;@Testpublic void test(){//指定交换机名称String exchangeName = "ttl.direct";//指定路由keyString routingKey = "ttl";//构建消息Message message = MessageBuilder.withBody("这是一条测试消息".getBytes(StandardCharsets.UTF_8)).setDeliveryMode(MessageDeliveryMode.PERSISTENT) //设置消息持久化.setExpiration("5000") //设置消息超时时间,单位:毫秒.build();// 发送消息rabbitTemplate.convertAndSend(exchangeName, routingKey, message);}}
