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超时分两种情况:

  • 消息所在的队列设置了存活时间
  • 消息本身设置了存活时间

根据上面流程图实现代码如下:

生产者代码:① 给消息添加时间

复制代码
    @Test
    public 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 {
    //声明交换机
    @Bean
    public DirectExchange ttlDirectExchange() {
        return new DirectExchange("ttl.direct");
    }

    //声明队列
    @Bean
    public Queue ttlQueue() {
        return QueueBuilder
                .durable("ttl.queuq")               //消息持久化
                .ttl(10000)                         //队列ttl时间
                .deadLetterExchange("dl.direct")    //死信交换机
                .deadLetterRoutingKey("dl")         //指定死信交换机的routingkey
                .build();
    }

    //绑定
    @Bean
    public 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为准。

三、应用场景

如,平时我们延迟发送短信,付款时间等等啊,都可以通过死信交换方式去实现这一流程!

相关推荐
明达智控技术11 小时前
告别停机内卷!热插拔远程IO,解锁工控运维新范式
分布式·物联网·自动化
漂着的圆木12 小时前
MCP 2026-07-28 长任务改造:别再用 HTTP 超时判断任务失败
分布式·架构·状态模式·ai agent
数智启示录18 小时前
Apache Kafka Consumer 扩到 40 个仍不提速:Partition 上限锁死有效并行度 【Kafka合集】
数据库·经验分享·分布式·缓存·面试·kafka·apache
数智启示录18 小时前
Apache Kafka 幂等 Producer 的边界:Exactly-Once 到了 MySQL 为什么失效 【Kafka合集】
数据库·经验分享·分布式·mysql·面试·kafka·apache
数智启示录18 小时前
Apache Kafka 不只是消息队列:日志与 Offset 分离如何让事件可重放 【Kafka合集】
经验分享·分布式·面试·kafka·apache
数智启示录18 小时前
Apache Kafka 同 Key 仍会乱序:从分区 Offset 到业务可见的四道边界 【Kafka 合集】
大数据·数据库·经验分享·分布式·面试·kafka·apache
BYSJMG18 小时前
大数据毕业设计选题推荐:基于大数据的全球气温历史演变分析与可视化,用Hadoop+Spark处理
大数据·hadoop·分布式·信息可视化·spark·kmeans·课程设计
爱吃苹果的梨叔18 小时前
AI 算力监控中心怎么建?分布式坐席 + 大屏联动 + 过程回放
人工智能·分布式·python
無a伟19 小时前
RabbitMQ :与AMQP的关系、核心组件、交换机类型
分布式·rabbitmq
jyOverQ1 天前
RabbitMQ 消息积压怎么办?Prefetch、消费者并发与扩容
分布式·后端·rabbitmq