RabbitMQ篇(死信交换机)
目录
一、简介
二、TTL过期时间
三、应用场景
一、简介
当一个队列中的消息满足下列情况之一时,可以成为死信(dead letter)
- 消费者使用basic.reject或者basic.nack声明消费失败,并且消息的requeue参数设置为false
- 消息是一个过期消息,超时无人消费
- 要投递的队列消息堆积满了,最早的消息可能成为死信 如果该队列配置了dead-letter-exchange属性,
指定了一个交换机,那么队列中的死信就会投递到这个交换机中,而且这个交换机称为死信交换机
(DeadLetter Exchange,简称DLX )。
什么样的消息会成为死信?
- 消息被消费者reject或者返回nack
- 消息超时未消费
- 队列满了
如何给队列绑定死信交换机?
- 给队列设置dead-letter-exchange属性,指定一个交换机
- 给队列设置dead-letter-routing-key属性,设置死信交换机与死信队列的Routingkey
二、TTL过期时间
TTL,也就是Tim-To-Live。如果一个队列中的消息TTL结束仍未消费,则会变为死信,ttl超时分两种情况:
- 消息所在的队列设置了存活时间
- 消息本身设置了存活时间
根据上面流程图实现代码如下:
生产者代码:① 给消息添加时间
@Testpublic void testTTLMessage() {// 1.准备消息Message message = MessageBuilder.withBody("hello, ttl messsage".getBytes(StandardCharsets.UTF_8)).setDeliveryMode(MessageDeliveryMode.PERSISTENT).setExpiration("5000") //指定消息的过期时间.build();// 2.发送消息rabbitTemplate.convertAndSend("ttl.direct", "ttl", message);// 3.记录日志log.info("消息已经成功发送!");}
消费者代码:② 给队列添加时间
//先绑定一个队列然后指定队列之后的死信交换机
//ttl消息发送
@Configuration
public class TTLMessageConfig {//声明交换机@Beanpublic DirectExchange ttlDirectExchange() {return new DirectExchange("ttl.direct");}//声明队列@Beanpublic Queue ttlQueue() {return QueueBuilder.durable("ttl.queuq") //消息持久化.ttl(10000) //队列ttl时间.deadLetterExchange("dl.direct") //死信交换机.deadLetterRoutingKey("dl") //指定死信交换机的routingkey.build();}//绑定@Beanpublic Binding ttlBinding() {return BindingBuilder.bind(ttlQueue()).to(ttlDirectExchange()).with("ttl");}
消费代码
@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "dl.queue"),exchange = @Exchange(name = "dl.direct", type = ExchangeTypes.DIRECT),key = "dl"))public void listenDLQueue(String msg) {log.debug("死信消息是:{}", msg);}
消息超时的两种方式是?
- 给队列设置ttl属性,进入队列后超过ttl时间的消息变为死信
- 给消息设置ttl属性,队列接收到消息超过ttl时间后变为死信
- 两者共存时,以消息端的ttl为准。
三、应用场景
如,平时我们延迟发送短信,付款时间等等啊,都可以通过死信交换方式去实现这一流程!