过期时间
RabbitMQ有两种方式可以设置消息的过期时间。第一种是通过队列属性设置,队列中所有的信息都有相同的过期时间,第二种方式是对消息本身进行单独设置,每条消息的TTL可以不同。如果两种方式一起中,则消息的TTL以两者之间较短的那个数值为准。消息在队列中的生存时间,一旦超过设置的TTL时,就会变成“死信”。
springboot中设置消息TTL的方式
设置队列属性
1 2 3 4 5 6
| @Bean public Queue ttlQueue() { Map<String, Object> param = new HashMap<>(); param.put("x-message-ttl", 1000 * 20); return new Queue("ttl-queue", true, false, false, param); }
|
这样就声明了一个带有20秒过期时间的队列,将它与交换机进行绑定,就能实现过期时间功能。
消息单独设置过期时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Test public void testMQ() throws InterruptedException { for (int i = 0; i < 10; i++) { MessagePostProcessor messagePostProcessor =new MessagePostProcessor() { @Override public Message postProcessMessage(Message message) throws AmqpException { message.getMessageProperties().setExpiration("10000"); return message; } }; rabbitTemplate.convertAndSend("config_exchange2", "kkk", "发送消息" + i,messagePostProcessor,new CorrelationData(String.valueOf(i))); } } }
|
如果为单独消息设置过期时间,需要编写MessagePostProcesssor中的message的expiration属性进行设置,注意过期时间要用字符串表示。
两种方式的区别
除了可以单独设置过期时间以外,第一种设置队列过期时间的方式,一旦消息过期,就会从队列中抹去,第二种方法,即使消息过期,也不会立刻从队列中抹去,而是每条消息是否过期时在即将投递到消费者之前进行判断的。
死信队列
DLX,全称为Dead-Letter-Exchange,死信交换机,当消息在一个队列中变成死信之后,它能被重新发送到死信交换机中,绑定了死信交换机的就是死信队列。
消息变成死信的情况
- 消息被拒绝,并且设置requeue参数为false;
- 消息过期
- 队列达到最大长度。
springboot设置死信队列
DLX也是一个正常的交换机,和一般的交换机没有区别,死信队列可以在任何队列上被指定,实际上就是给队列设置一个死信交换机的属性。当这个队列中有死信时,rabbitMQ就会把消息重新发送给设置的DLX中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| 1、声明队列和死信交换机并进行绑定 @Bean public TopicExchange DLX() { TopicExchange topicExchange = new TopicExchange("DLX", true, false); return topicExchange; }
@Bean public Queue DLQ(){ return new Queue("DLQ",true,false,false); }
@Bean public Binding DLXBinding(){ return BindingBuilder.bind(DLQ()).to(DLX()).with("*.b.*"); } 2、给队列指定死信交换机 @Bean public Queue ttlQueue() { Map<String, Object> param = new HashMap<>(); param.put("x-message-ttl", 10000); param.put("x-dead-letter-exchange", "DLX"); return new Queue("ttl-queue", true, false, false, param); }
|
整体设置死信队列的逻辑就是:
- 声明一个新的队列
- 声明一个新的交换机(作为死信交换机,为了能够成功将消息路由给死信队列,要保持交换机类型和要绑定的交换机相同,例如 A是Topic类型的交换机,那么作为A的队列的死信交换机,也要用Topic类型)
- 完成交换机和队列之间的绑定(这里要注意路由键的问题,保证路由键和原来的相同,这样才能正常的将死信路由过来)
- 给原来的交换机绑定的队列配置死信交换机,命令是
"x-dead-letter-exchange", “死信交换机名称”