本文主要是介绍大聪明教你学Java | 深入浅出聊 RabbitMQ 中的死信队列和延迟队列,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前言
🍊作者简介: 不肯过江东丶,一个来自二线城市的程序员,致力于用“猥琐”办法解决繁琐问题,让复杂的问题变得通俗易懂。
🍊支持作者: 点赞👍、关注💖、留言💌~
今天大明白在用 RabbitMQ 的时候又被难住了 👇
大明白:兄弟,RabbitMQ 你用过不?😥
大聪明:那必须用过啊,你这是又被什么问题给难住了 🤔
大明白:我用 RabbitMQ 的时候就是发个消息到消费者就结束了,今天才知道还有死信队列和延迟队列呢,这都是啥玩意啊😭
大聪明:哈哈哈哈哈哈哈哈,小问题,不要慌~ 正好今天没啥事,听我给你娓娓道来…
RabbitMQ 中的死信队列
在了解死信队列之前,我们先来看看什么是死信👇
死信,顾名思义就是无法被消费的消息。一般来说,生产者将消息投递到某个节点或者直接投递到某个队列里,消费者从队列中取出消息进行消费,但有时候由于特定的原因导致队列中的某些消息无法被消费,这些无法被消费的消息如果没有后续的处理,那么就变成了死信,有死信自然就有了死信队列,即 DLX(Dead Letter Exchanges )。
在死信的概念中,我们可以看到这么一个关键词“特定的原因”,我们再一起看看这个特定的原因具体指得的什么:
- 消息 TTL (Time to live的简称,即过期时间)过期
- 队列达到最大长度(队列满了,无法再将新消息添加数据到队列中)
- 消息被拒绝(basic.reject 或 basic.nack)并且 requeue=false
我们可以参考下面的流程图来理解消息被投递到死信队列的过程 👇
其实死信队列并没有什么独特的地方,它不过是绑定在死信交换机上的普通队列,而死信交换机也只是一个普通的交换机,不过是用来专门处理死信的交换机。死信消息的生命周期也并不复杂:
- 业务消息被投入业务队列
- 消费者正常消费业务队列的消息,但是由于处理过程中发生异常,于是进行了 basic.reject 或 basic.nack 操作
- 被 basic.reject 或 basic.nack 的消息由 RabbitMQ 投递到死信交换机中
- 死信交换机将消息投入相应的死信队列
- 死信队列的消费者消费死信消息
我们了解了死信队列的基本概念,可能有些小伙伴就会产生疑问了:既然死信队列中的消息都是死信,那它有什么用呢?成了死信直接删掉不就行了吗🤨
其实死信消息是 RabbitMQ 为我们做的一层保证。当然了,我们也可以不使用死信队列,而是在消息消费异常时,将消息主动投递到另一个交换机中。比如从死信队列拉取消息,然后发送邮件、短信等方式来通知开发人员关注;或者将消息重新投递到一个队列然后设置过期时间,来进行延时消费。一般用在较为重要的业务队列中,确保未被正确消费的消息不被丢弃,一般发生消费异常可能的原因主要由于消息信息本身存在错误导致处理异常,处理过程中参数校验异常,或者因网络波动导致的查询异常等等。当发生异常时,当然不能每次通过日志来获取原消息,然后让运维帮忙重新投递消息。此时就可以通过配置死信队列的方式来解决这个问题,我们可以让未正确处理的消息暂存到另一个队列中,待后续排查清楚问题后,编写相应的处理代码来处理死信消息。这样的处理方式是不是就比手工投递消息要好太多了😉
RabbitMQ 中的延迟队列
延迟队列存储的对象是对应的延迟消息。所谓“延迟消息” 是指当消息被发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后,消费者才能拿到这个消息进行消费,简单来说,延时队列就是用来存放需要在指定时间被处理的元素的队列。在 RabbitMQ 中并没有直接给我们提供延迟队列的功能,我们可以通过 “过期时间 + 死信队列” 的方式来实现延迟队列。如下图所示:
延迟队列的应用场景就非常多了,比如:
- 用户在商城下单,此时库存减一;若30分钟未支付,则取消该订单,将商品库存加一(即订单30分钟未支付,系统自动超时关闭)
- 账单 24 小时未确认,就发送提醒消息
在这里我们可以延伸出来一个问题:我们在实现订单30分钟未支付,系统自动超时关闭的时候,为什么选择延迟队列呢?有没有其他的实现方案呢?👇
答案是肯定的,一定是存在其他实现方案的,下面我们就对这些方案做一个对比:
🍊 方案一:基于任务调度实现(也就是利用定时任务轮询数据库实现)。估计没人会选择这种实现方式,它的弊端太明显了,效率非常低,也非常消耗服务器性能。
🍊 方案二:…
🍊 方案三:…
嘿嘿,这里我先卖个关子,欲知后事如何,且听下回分解👋
小结
本人经验有限,有些地方可能讲的没有特别到位,如果您在阅读的时候想到了什么问题,欢迎在评论区留言,我们后续再一一探讨🙇
希望各位小伙伴动动自己可爱的小手,来一波点赞+关注 (✿◡‿◡) 让更多小伙伴看到这篇文章~ 蟹蟹呦(●’◡’●)
如果文章中有错误,欢迎大家留言指正;若您有更好、更独到的理解,欢迎您在留言区留下您的宝贵想法。
你在被打击时,记起你的珍贵,抵抗恶意;
你在迷茫时,坚信你的珍贵,抛开蜚语;
爱你所爱 行你所行 听从你心 无问东西
这篇关于大聪明教你学Java | 深入浅出聊 RabbitMQ 中的死信队列和延迟队列的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!