死信交换机与延迟队列
死信交换机
满足下列情况一点,即为死信(dead letter):
消费者使用 basic.reject 或 basic.nack 声明消费失败,并且消息的 requeue 参数设置为 false。消息是一个过期消息,超时无人消费。要投递的队列满了,最早的消息可能成为死信。
假设该队列配置了 dead-letter-exchange 属性,指定了一个交换机,那么队列中的死信就会投递到这个交换机中,这个交换机就叫 死信交换机(DLX)。
死信交换机与前文的异常交换机的区别:死信交换机是 Queue 发送消息,而异常交换机是 consumer 发送消息。
给队列绑定死信交换机:
给队列设置 dead-letter-exchange 属性,指定一个交换机。给队列设置 dead-letter-routing-key 属性,设置死信交换机与死信队列的 RoutingKey。
延迟队列
假设一个队列中的消息 TTL 完毕仍未消费,则会变成死信,ttl 超时分为两种情况:
消息所在队列设置了存活时间。消息自身设置了存活时间。当队列和消息都有存活时间时,依照最小存活时间生效。
延迟队列:
利用 TTL 结合死信交换机,实现发送消息后,消费者延迟收到消息的效果。这种消息形式就称为延迟队列(Delay Queue)形式。
延迟队列的使用场景:
延迟发送信息。用户下单,假设用户限定时间内未支付,自动取消。
TTL 结合死信交换机完成延迟队列功能:
延迟队列创建:- @Beanpublic DirectExchange ttlDirectExchange(){returnnewDirectExchange("ttl.direct");}@Beanpublic Queue ttlQueue(){return QueueBuilder
- .durable("ttl.queue")// 耐久化.ttl(10000)// 设置超时时间.deadLetterExchange("dl.direct")// 死信交换机.deadLetterRoutingKey("dl")// 死信RoutingKey.build();}@Beanpublic Binding ttlBinding(){return BindingBuilder.bind(ttlQueue()).to(ttlDirectExchange()).with("ttl");}
复制代码 发送延时消息:- @TestpublicvoidtestTTLMessage(){// 1. 准备消息
- Message message = MessageBuilder.withBody("hello, ttl message".getBytes(StandardCharsets.UTF_8)).setDeliveryMode(MessageDeliveryMode.PERSISTENT)// 耐久化消息设置.setExpiration("5000")// 设置消息的超时时间.build();// 2. 发送消息
- rabbitTemplate.convertAndSend("ttl.direct","ttl", message);// 3. 记录日志
- log.info("消息已经胜利发送!");}
复制代码 |