热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

RabbitMQ队列有Unacked消息,但无消费者信息

问题业务反馈线上队列无消费者,但是management管理端发现有Unacked量基本原理Unacked消息指的是服务端已经投递给消费者,但还没有收到消费者响应Ack这么一个中间状

问题

业务反馈线上队列无消费者,但是management管理端发现有Unacked量


基本原理

  1. Unacked消息指的是服务端已经投递给消费者,但还没有收到消费者响应Ack这么一个中间状态。
  2. 消费者假如在消费过程中(尚未给Broker响应Ack)退出,那么消费中的这部分Unacked消息会被requeue到队列,进而投递到其余消费者(假如有Consumers在线);假如没有Consumers,那这部分Unacked消息会转换为Ready状态。
  3. Unacked消息状态被Broker维护在内存中。

而上面截图的问题:队列有Unacked量,但是没有Consumers信息,似乎很矛盾。

定位

阅读服务端消费相关板块代码,发现 rabbit_queue_consumers 板块:

计算Unacked消息量

unacknowledged_message_count() -> lists:sum([queue:len(C#cr.acktags) || C <- all_ch_record()]).

读进程字典

all_ch_record() -> [C || {{ch, _}, C} <- get()].

写进程字典

store_ch_record(C = #cr{ch_pid = ChPid}) -> put({ch, ChPid}, C), ok.

rabbit_queue_consumers 板块实际是被 rabbit_amqqueue_process 调用。不难发现队列进程进程字典维护消息消费过程中的消费Channel进程等信息。

验证

  1. 启动Erlang shell

erl -name sj@test -setCOOKIE COOKIE名

  1. 获取队列amqqueue记录信息,其中包含进程pid等信息。

rpc:call(N,erlang,apply,[fun()->rabbit_amqqueue:lookup(rabbit_misc:r(<<"vhost名字">>,queue,<<"queue名字">>)) end,[]]).

  1. 获取队列进程进程字典信息。Pid为步骤2获取到的进程Pid

rpc:call(node(Pid), erlang, process_info, [Pid,dictionary]).

最终发现了相似如下6条关键信息,与问题中的Unacked量对应:

{{ch,<8232.16445.2870>}, {cr,<8232.16445.2870>,#Ref<8251.0.972816396.42542>, {[{3,<<"amq.ctag-RkzjrIA60GwE9ED8opKK7w">>}],[]}, 0, {queue,[],[],0}, {qstate,<8232.16442.2870>,dormant,{0,nil}}, 1}}

处理

已经能找到上述Unacked状态的6条消息对应的Channel进程,如何让这些消息重入队(成为Ready状态)?

阅读服务端代码,发现 rabbit_amqqueue_process 板块 handle_ch_down/2 方法,该方法内部调用 rabbit_queue_consumers 板块 erase_ch/2 方法,
最终调用 erase/2 将 {ch, ChPid} 这个key从进程字典中移除。

因而,可以通过触发channel进程DOWN

exit(ChPid,normal).

最终队列进程感知Channel进程退出,进而将Unacked状态requeue,最终消息转变为Ready状态~

拓展

如何获取队列Unacked状态消息?

sys:get_state(Pid).

有兴趣可以调试下


推荐阅读
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • BZOJ1233 干草堆单调队列优化DP
    本文介绍了一个关于干草堆摆放的问题,通过使用单调队列来优化DP算法,求解最多可以叠几层干草堆。具体的解题思路和转移方程在文章中进行了详细说明,并给出了相应的代码示例。 ... [详细]
  • mapreduce源码分析总结
    这篇文章总结的非常到位,故而转之一MapReduce概述MapReduce是一个用于大规模数据处理的分布式计算模型,它最初是由Google工程师设计并实现的ÿ ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 摘要: 在测试数据中,生成中文姓名是一个常见的需求。本文介绍了使用C#编写的随机生成中文姓名的方法,并分享了相关代码。作者欢迎读者提出意见和建议。 ... [详细]
  • 本文讨论了Kotlin中扩展函数的一些惯用用法以及其合理性。作者认为在某些情况下,定义扩展函数没有意义,但官方的编码约定支持这种方式。文章还介绍了在类之外定义扩展函数的具体用法,并讨论了避免使用扩展函数的边缘情况。作者提出了对于扩展函数的合理性的质疑,并给出了自己的反驳。最后,文章强调了在编写Kotlin代码时可以自由地使用扩展函数的重要性。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • 使用C++编写程序实现增加或删除桌面的右键列表项
    本文介绍了使用C++编写程序实现增加或删除桌面的右键列表项的方法。首先通过操作注册表来实现增加或删除右键列表项的目的,然后使用管理注册表的函数来编写程序。文章详细介绍了使用的五种函数:RegCreateKey、RegSetValueEx、RegOpenKeyEx、RegDeleteKey和RegCloseKey,并给出了增加一项的函数写法。通过本文的方法,可以方便地自定义桌面的右键列表项。 ... [详细]
  • Apache Shiro 身份验证绕过漏洞 (CVE202011989) 详细解析及防范措施
    本文详细解析了Apache Shiro 身份验证绕过漏洞 (CVE202011989) 的原理和影响,并提供了相应的防范措施。Apache Shiro 是一个强大且易用的Java安全框架,常用于执行身份验证、授权、密码和会话管理。在Apache Shiro 1.5.3之前的版本中,与Spring控制器一起使用时,存在特制请求可能导致身份验证绕过的漏洞。本文还介绍了该漏洞的具体细节,并给出了防范该漏洞的建议措施。 ... [详细]
  • 本文介绍了使用readlink命令获取文件的完整路径的简单方法,并提供了一个示例命令来打印文件的完整路径。共有28种解决方案可供选择。 ... [详细]
  • 1.脚本功能1)自动替换jar包中的配置文件。2)自动备份老版本的Jar包3)自动判断是初次启动还是更新服务2.脚本准备进入ho ... [详细]
  • 项目需要将音视频文件上传服务器,考虑并发要求高,通过七牛来实现。直接上代码usingQiniu.IO;usingQiniu.IO.Resumable;usingQiniu.RPC; ... [详细]
author-avatar
mobiledu2502858037
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有