生产环境中,RabbitMQ 持续积压消息不进行ack ,发生什么了?

简介: 生产环境中,RabbitMQ 持续积压消息不进行ack ,发生什么了?

问题:生产环境 rabbitmq 部分客户端 channel 持续积压消息不进行ack。


0. 服务配置


  • rabbitmq 集群(普通集群模式)


  • 消费者 三台 消费线程各消费者 10


  • 消费者配置 使用 spring-amqp|auto-ack 模式


1. 故障发现


近日有同学发现一个业务队列存在上千个 unacked 消息,并且有持续上涨的趋势。


2. 故障表现


队列下其中两个客户端的各一个 channel 分别阻塞几百条数据,并且在持续累加,重启应用后队列 unacked 消息全部进入 ready 状态等待重消费,但是重启后客户端依然有 channel 重新开始堆积并且在趋势上涨。


3. 问题排查


排查思路


  • 检查 mq 控制台是否是队列创建问题


  • 消费者阻塞是否有规律可循(未ack数据是否有共同特征、阻塞客户端配置是否有问题)


  • 客户端代码是否有问题、应用是否有jvm级别故障


4. 问题定位


经过一番筛查,问题定位到了代码部分,队列消费代码并非刚上线,而是在前一日服务重启后出现的这个问题,重新 review 代码后发现消费者有使用 CountDownLatch 等待多线程消费结果,CountDownLatch#countDown 的调用没有放到 finally 中执行,并且提交到线程池的任务也没有使用 try catch 进行包裹。


到此怀疑是消费线程阻塞到了 CountDownLatch#await 处,异步任务处理时由于偶现异常代码并未执行到 CountDownLatch#countDown 处,再者由于异步任务未捕获异常导致错误直接抛到 jvm 日志无法记录错误。


为了验证这个问题,我们又dump了阻塞服务的栈信息,发现确实有消费者线程阻塞到 CountDownLatch#await 处,问题定位结束。


5. 解决方案


从任务处下手添加 catch 记录日志,并将 CountDownLatch#await 放到 finally 中执行。重启应用再次观察,并未出现 unacked 消息,观察日志也并未出现新添加的 error 日志。


6.问题拓展


同一个 channel 为何会阻塞那么多数据?


线上生产环境采用推模式,rabbitmq 通过 channel 推送消息到客户端,客户端采用 LinkedBlockingQueue 做缓存,一个 channel 对应一个消费者线程,当消费者线程阻塞时 LinkedBlockingQueue 作为中转一直在预存消息,所以会出现很多 unacked 消息。


为什么仅有部分一两个 channel 出现堆积?


线上添加错误日志后实际并未出现错误打印,怀疑之前异常可能是由于重启后第一次请求 rpc 偶现调用失败,猜测暂无法复现,后续需观察日志。


总结


  • 谨慎使用线程同步,谨防线程死锁,务必保证线程不会 hang死。


  • 自建线程池做好错误兜底,不要将异常抛给jvm。


推荐好文


>>【练手项目】基于SpringBoot的ERP系统,自带进销存+财务+生产功能


>>分享一套基于SpringBoot和Vue的企业级中后台开源项目,代码很规范!

>>能挣钱的,开源 SpringBoot 商城系统,功能超全,超漂亮!

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
1月前
|
存储 Kubernetes API
K8S上生产环境后,90%都会遇到这个故障
K8S上生产环境后,90%都会遇到这个故障
30 0
|
7月前
|
消息中间件 存储 Kubernetes
k8s1.20版本部署RabbitMQ集群(持久化)——2023.05
k8s1.20版本部署RabbitMQ集群(持久化)——2023.05
276 1
|
5月前
|
弹性计算 资源调度 Kubernetes
Flink三种集群模式,Standalone模式,Flink On YARN,Flink On K8S,这三种模式有啥优缺点,生产环境如何选择呢?
Flink三种集群模式,Standalone模式,Flink On YARN,Flink On K8S,这三种模式有啥优缺点,生产环境如何选择呢?
242 3
|
7月前
|
消息中间件 NoSQL 关系型数据库
【Kubernetes部署Shardingsphere、Mycat、Mysql、Redis、中间件Rocketmq、Rabbitmq、Nacos】
【Kubernetes部署Shardingsphere、Mycat、Mysql、Redis、中间件Rocketmq、Rabbitmq、Nacos】
135 0
|
7月前
|
Kubernetes Devops 容器
生产环境实现k8s多集群管理
生产环境实现k8s多集群管理
|
7月前
|
运维 Kubernetes jenkins
【Kubernetes测试生产环境整体部署及全链路测试、自动化运维平台Jenkins与Devops环境搭建】
【Kubernetes测试生产环境整体部署及全链路测试、自动化运维平台Jenkins与Devops环境搭建】
224 0
|
10月前
|
消息中间件
rabbitmq消息的确认机制ack
rabbitmq消息的确认机制ack
|
10月前
|
存储 消息中间件 Kubernetes
K8s生产环境常见问题处理、答疑(连载、不定期更新)
K8s生产环境常见问题处理、答疑(连载、不定期更新)
2813 0
|
12月前
|
消息中间件
RabbitMQ手动ACK与死信队列
RabbitMQ手动ACK与死信队列
156 0
|
消息中间件 存储 前端开发
硬核!SpringBoot集成RabbitMQ消息队列搭建与ACK消息确认入门
硬核!SpringBoot集成RabbitMQ消息队列搭建与ACK消息确认入门
387 0
硬核!SpringBoot集成RabbitMQ消息队列搭建与ACK消息确认入门

推荐镜像

更多