死信队列

引言

死信队列,英文缩写:DLX 。Dead Letter Exchange(死信交换机),其实应该叫做死信交换机才更恰当。

当消息成为Dead message后,可以被重新发送到另一个交换机,这个交换机就是DLX。

总结:其实死信队列就是一个普通的交换机,有些队列的消息成为死信后,(比如过期了或者队列满了)这些死信一般情况下是会被 RabbitMQ 清理的。但是你可以配置某个交换机为此队列的死信交换机,该队列的消息成为死信后会被重新发送到此 DLX 。至于怎么处理这个DLX中的死信就是看具体的业务场景了,DLX 中的信息可以被路由到新的队列。

消息成为死信的三种情况

  • 队列长度到达限制,无法加入新的消息
  • 消费者拒接消费消息,并且不重回队列。该信息会被清除并进入死信队列
  • 原队列存在消息过期设置,消息到达超时时间未被消费

队列如何绑定 DLX

  • x-dead-letter-exchange 指定此队列的死信队列
  • x-dead-letter-exchange 指定此队列向DLX发送死信的routing key,因为这个时候该队列相当于一个生产者,发送消息要指定routing key

实现效果:往一个普通队列添加消息,消息过期成为死信,进入死信队列。死信队列根据配置好的route key 路由到与它绑定的其他普通队列。

  1. 声明死信队列(普通交换机)

        // 声明死信交换机
    @Bean("deadExchange")
    public Exchange deadExchange(){
    return ExchangeBuilder.topicExchange("sb_dead_exchange").durable(true)
    .autoDelete().build();
    }
  2. 声明普通队列,配置它的DLX

        // 声明普通队列,绑定死信队列
    @Bean
    public Queue queue3(){
    Queue build = QueueBuilder.durable("sb_dead_queue").build();
    build.addArgument("x-message-ttl",10000);
    build.addArgument("x-dead-letter-exchange","sb_dead_exchange");
    // 此时队列相当于生产者,因此要指定消息的routing key,死信队列可以更加routing key路由到其他队列
    build.addArgument("x-dead-letter-routing-key","user4.info");
    return build;
    }
    // 绑定此队列和它的交换机
    @Bean
    public Binding exchangQueue3(@Qualifier("queue3")Queue queue,
    @Qualifier("topicExchange") Exchange exchange){
    return BindingBuilder.bind(queue).to(exchange).with("user3.#").noargs();
    }
  3. 绑定死信队列和普通队列,死信队列中的消息会根据路由发送到其他队列

        // 绑定死信队列和普通队列
    @Bean
    public Binding exchangQueue4(@Qualifier("queue2")Queue queue,
    @Qualifier("deadExchange") Exchange exchange){
    return BindingBuilder.bind(queue).to(exchange).with("user4.#").noargs();
    }

    延迟队列

    延迟队列,即消息进入队列后不会立即被消费,只有到达指定时间后,才会被消费。经典的应用场景是下单减库存。

    预扣库存的模式下,我们下单会立刻减库存,但是超过支付时间还没支付的话该订单就会被取消,库存回滚。

    具体实现可以采用定时器的方式,定时检查当前时间与下单时间是否超过上限,比如设置为30min。但是多久执行一次定时任务是个问题,精度大(比如1s执行一次)的话数据库的压力十分大,精度小(比如2min执行一次)的话又会带来误差。

    现在采用的方式是采用延迟队列。RabbitMQ没有提供延迟队列的功能。但是我们能使用死信队列 + TTL 自己实现延迟队列。TTL时间为过期时间(如30min)。

    我们为每条订单信息设置一个过期时间(30min),消息过期后成为死信,自动进入死信队列,死信队列又把消息路由到它绑定的普通队列,库存系统订阅该队列即可在30min后才取出该信息。间接实现了延迟队列的功能

    如此设计库存系统就一定只能在30min后才能从队列中取出订单

消息队列RabbitMQ(五):死信队列与延迟队列的更多相关文章

  1. RabbitMQ 入门教程(PHP版) 延迟队列,延迟任务

    延迟任务应用场景 场景一:物联网系统经常会遇到向终端下发命令,如果命令一段时间没有应答,就需要设置成超时. 场景二:订单下单之后30分钟后,如果用户没有付钱,则系统自动取消订单. 场景三:过1分钟给新 ...

  2. 【RabbitMQ 实战指南】一 延迟队列

    1.什么是延迟队列 延迟队列中存储延迟消息,延迟消息是指当消息被发送到队列中不会立即消费,而是等待一段时间后再消费该消息. 延迟队列很多应用场景,一个典型的应用场景是订单未支付超时取消,用户下单之后3 ...

  3. RabbitMQ 延迟队列,消息延迟推送

    目录 应用场景 消息延迟推送的实现 测试结果 应用场景 目前常见的应用软件都有消息的延迟推送的影子,应用也极为广泛,例如: 淘宝七天自动确认收货.在我们签收商品后,物流系统会在七天后延时发送一个消息给 ...

  4. C#实现rabbitmq 延迟队列功能

    最近在研究rabbitmq,项目中有这样一个场景:在用户要支付订单的时候,如果超过30分钟未支付,会把订单关掉.当然我们可以做一个定时任务,每个一段时间来扫描未支付的订单,如果该订单超过支付时间就关闭 ...

  5. 如何用RabbitMQ实现延迟队列

    前言 在 jdk 的 juc 工具包中,提供了一种延迟队列 DelayQueue.延迟队列用处非常广泛,比如我们最常见的场景就是在网购或者外卖平台中发起一个订单,如果不付款,一般 15 分钟后就会被关 ...

  6. RabbitMQ如何实现延迟队列?(转)

    什么是延迟队列 延迟队列存储的对象肯定是对应的延迟消息,所谓"延迟消息"是指当消息被发送以后,并不想让消费者立即拿到消息,而是等待指定时间后,消费者才拿到这个消息进行消费. 场景一 ...

  7. Java 延迟队列使用

    延时队列,第一他是个队列,所以具有对列功能第二就是延时,这就是延时对列,功能也就是将任务放在该延时对列中,只有到了延时时刻才能从该延时对列中获取任务否则获取不到…… 应用场景比较多,比如延时1分钟发短 ...

  8. Dyno-queues 分布式延迟队列 之 基本功能

    Dyno-queues 分布式延迟队列 之 基本功能 目录 Dyno-queues 分布式延迟队列 之 基本功能 0x00 摘要 0x01 Dyno-queues分布式延迟队列 1.1 设计目标 1. ...

  9. Dyno-queues 分布式延迟队列 之 生产消费

    Dyno-queues 分布式延迟队列 之 生产消费 目录 Dyno-queues 分布式延迟队列 之 生产消费 0x00 摘要 0x01 前情回顾 1.1 设计目标 1.2 选型思路 0x02 产生 ...

  10. Dyno-queues 分布式延迟队列 之 辅助功能

    Dyno-queues 分布式延迟队列 之 辅助功能 目录 Dyno-queues 分布式延迟队列 之 辅助功能 0x00 摘要 0x01 前文回顾 0x2 Ack机制 2.1 加入Un-ack集合 ...

随机推荐

  1. 一种3位sar adc工作过程推导(二)

    3位sar adc采用下图的电容阵列,需要23个电容,它的基本单元有二进制加权的电容阵列.1个与LSB电容等值的电容:它利用电容上的初始电荷再分配完成二进制搜索算法,因此功耗一般比较小,而且不需要额外 ...

  2. 实验一 Python程序设计入门

    学号20184307 2019-2020-2 <Python程序设计>实验1报告 课程:<Python程序设计> 班级: 1843 姓名: 章森洋 学号:20184307 实验 ...

  3. .Net Core3.1中SameSite的使用方法、遇到的问题以及解决办法

    一.关于SameSite的介绍 1.  什么是SameSite? SameSite是浏览器请求中Set-Cookie响应头新增的一种属性,它用来标明这个 cookie 是否是"同站 cook ...

  4. PAT (Basic Level) Practice (中文)1055 集体照 (25 分) 凌宸1642

    PAT (Basic Level) Practice (中文)1055 集体照 (25 分) 凌宸1642 题目描述: 拍集体照时队形很重要,这里对给定的 N 个人 K 排的队形设计排队规则如下: 每 ...

  5. 提高Python的性能

    01 使用哈希表的数据结构   如果在程序中遇到大量搜索操作时,并且数据中没有重复项,则可以使用查找而不是循环.举例如下: items = ['a', 'b',..,'100m'] #1000s of ...

  6. Scrapy 5+1 ——五大坑附送一个小技巧

    笔者最近对scrapy的学习可谓如火如荼,虽然但是,即使是一整天地学习下来也会有中间两三个小时的"无效学习",不是笔者开小差,而是掉进了深坑出不来. 在此,给各位分享一下作为一名S ...

  7. Spring Cloud Alibaba(2)---Nacos概述

    Spring Cloud Alibaba(2)---nacos概述 上一篇博客讲了有关 SpringCloudAlibaba的概述,这篇开始讲SpringCloudAlibaba组件之一---Naco ...

  8. MRCTF My secret

    My secret 知识点:wireshark基本操作,shadowsocks3.0源码利用,拼图(os脚本编写能力), 根据这里的信息可以知道,tcp所传输的源数据是在target address后 ...

  9. 给出N个字符串恰好由三位字母(大小写)组成,再给出M个查询字符串,问每个查询字符串在N个字符中出现的次数。

    1 #include<cstdio> 2 const int maxn = 100; 3 char S[maxn][5], temp[5]; 4 int hashTable[52 * 52 ...

  10. SpringCloud-微服务架构编码构建

    SpringCloud Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线).分布式系统的协调导致了样板模式, ...