# 过期时间
RabbitMQ 有两种方式可以设置消息的过期时间。第一种是通过队列属性设置,队列中所有的信息都有相同的过期时间,第二种方式是对消息本身进行单独设置,每条消息的 TTL 可以不同。** 如果两种方式一起中,则消息的 TTL 以两者之间较短的那个数值为准。** 消息在队列中的生存时间,一旦超过设置的 TTL 时,就会变成 “死信”。
# springboot 中设置消息 TTL 的方式
# 设置队列属性
@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 秒过期时间的队列,将它与交换机进行绑定,就能实现过期时间功能。
# 消息单独设置过期时间
@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、声明队列和死信交换机并进行绑定 | |
@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", “死信交换机名称”