一次RocketMQ ons SDK Bug导致消息不断堆积到重试队列的案例分析

2022年10月30日00:38:35 科技 1434

背景介绍

系统运行在专有云,应用运行时环境是EDAS Container( EDAS Container是EDAS 平台 HSF 应用运行的基础容器,EDAS Container 包含 Ali-Tomcat 和 Pandora),消息处理使用的是【ons SDK】,消息消费者使用【PUSH】方式【批量】消费【普通消息】,MessageModel是【CLUSTERING】。
为了解决RocketMQ Producer某个性能问题,对Pandora进行了升级(主要是升级RocketMQ版本)。
下面从技术角度对升级中遇到的问题及分析过程进行总结,积累经验以避免类似问题的发生。

问题描述

Pandora升级完成后,我们在RocketMQ控制台看到【消费者状态】->【实时消息堆积量】有8亿条,而每个Consumer实例堆积量是几十条,如图1:

一次RocketMQ ons SDK Bug导致消息不断堆积到重试队列的案例分析 - 天天要闻

图1

在【消费者状态】->【连接详情】有消息消费失败的情况,如图2:

一次RocketMQ ons SDK Bug导致消息不断堆积到重试队列的案例分析 - 天天要闻

图2

在应用服务器ons.log也可以实时查看消息消费的指标信息,如图3:

一次RocketMQ ons SDK Bug导致消息不断堆积到重试队列的案例分析 - 天天要闻

图3

这部分的统计指标的实现可以查看:org.apache.rocketMQ.client.stat.ConsumerStatsManager

分析过程

根据我们前面几篇关于MQ消息堆积的文章,可以知道:

  1. 消息堆积总量与Consumer实例消息堆积量相符的情况下,通常是Consumer消费能力弱导致堆积,详情见:

一次RocketMQ ons SDK Bug导致消息不断堆积到重试队列的案例分析 - 天天要闻

图4

为了便于理解,我们使用流程图来表达下图4中代码主要逻辑,见图5:

一次RocketMQ ons SDK Bug导致消息不断堆积到重试队列的案例分析 - 天天要闻

图5

分析上面流程及代码,发现ConsumeConcurrentlyContext类的ackIndex变量是分析消息成功与失败的核心变量。

是否业务处理异常?

RocketMQ框架在业务处理类出现下面情况的时候,认为消息消费失败:

  1. 业务处理类返回ConsumeConcurrentlyStatus.RECONSUME_LATER
  2. 业务处理类返回null
  3. 业务处理类抛出异常

通过业务处理类日志可以确定业务没有返回ConsumeConcurrentlyStatus.RECONSUME_LATER的情况;
从代码可以看出,当出现2、3情况的时候,框架会将warn日志打印到ons.log中,通过过滤ons.log中“consumeMessage exception”和“consumeMessage return null”关键词,没有相应的日志记录,所以也不是这两种情况造成的。
备注:
当出现2、3情况的时候,ons.log日志中并没有打印出线程栈信息,如果想具体定位异常产生的位置,可以通过arthas stack命令进行分析。

arthas watch processConsumeResult

既然发送失败消息到Broker重试队列是在processConsumeResult方法调用的,那么我们可以分析下该方法的入参及返回值情况。

watch com.alibaba.rocketmq.client.impl.consumer.ConsumeMessageConcurrentlyService 
processConsumeResult "{params,returnObj}" "target.consumeGroup=='GID_CID_XXX'" -x 3 -n3

watch正常机器

一次RocketMQ ons SDK Bug导致消息不断堆积到重试队列的案例分析 - 天天要闻

图6

watch异常机器

一次RocketMQ ons SDK Bug导致消息不断堆积到重试队列的案例分析 - 天天要闻

图7

通过上面的watch,我们找到了问题最关键的地方,我们用下面的场景来分析下ackIndex不同值的影响。
场景一

  1. 业务处理类批量消费了【8】条数据,消费成功返回:CONSUME_SUCCESS
  2. ackIndex=Integer.MAX_VALUE
  3. RocketMQ框架分析消费成功了【8】条,失败【0】条
  4. 因为都消费成功了,不会将消息发送到Broker重试队列中

场景二

  1. 业务处理类批量消费了【8】条数据,消费成功返回:CONSUME_SUCCESS
  2. ackIndex=0
  3. RocketMQ框架分析消费成功了【1】条,失败【7】条
  4. 因为有【7】条消费失败,所以会将【7】条消费失败的消息发送到Broker重试队列中

arthas watch setAckIndex

既然有地方在修改ackIndex,先验证下我们的判断是否正确。

watch com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext setAckIndex "{params,returnObj}" "params[0]==0"

通过观察,确实有地方在不断将ackIndex的值修改为0。

arthas stack setAckIndex

我们继续定位是什么地方将ackIndex修改为0的。

stack com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext setAckIndex "{params,returnObj}" "params[0]==0"

一次RocketMQ ons SDK Bug导致消息不断堆积到重试队列的案例分析 - 天天要闻

图8

通过线程栈可知BatchConsumerImpl类调用了ConsumeConcurrentlyContext.setAckIndex方法。

arthas jad BatchConsumerImpl

没有源码的情况下,我们可以使用arthas jad对类进行反编译。

jad com.aliyun.openservices.ons.api.impl.rocketmq.BatchConsumerImpl

一次RocketMQ ons SDK Bug导致消息不断堆积到重试队列的案例分析 - 天天要闻

图9

ConsumeContext类实例字段acknowledgeIndex默认值是多少呢?如果是0,问题的原因就找到了。

athas jad ConsumeContext

没有源码的情况下,我们可以使用arthas jad对类进行反编译。

jad com.aliyun.openservices.ons.api.ConsumeContext

一次RocketMQ ons SDK Bug导致消息不断堆积到重试队列的案例分析 - 天天要闻

图10

通过上面代码可以看出,ConsumeContext类实例字段acknowledgeIndex的默认值是0。

ProcessQueue

通过上面的分析,我们已经定位到了问题,ProcessQueue做下简单描述,不做具体分析了。

一次RocketMQ ons SDK Bug导致消息不断堆积到重试队列的案例分析 - 天天要闻

图11

解决办法

由上面的分析,这个问题属于RocketMQ ons SDK的一个Bug,修复就交给相应的产研团队来fix吧。

经验总结

1-5-10,1分钟发现,5分钟定位,10分钟恢复。
当故障发生的时候,需要【1】最短时间内发现(监控报警是否做好),需要【10】最快的速度恢复(变更管理和预案是否做好),【5】似乎不是最主要的。

科技分类资讯推荐

数字化汽车设计的开山之作 Romulus Predator - 天天要闻

数字化汽车设计的开山之作 Romulus Predator

1997年,一款名为Romulus Predator的超级跑车在底特律的AutoFact汽车展上首次亮相,这款车型在汽车工业发展史上具有里程碑式的意义。Romulus Predator被誉为世界上第一款完全使用计算机技术开发设计的汽车,标志着汽车设计进入了全新
柔韧的手撕钢、会写毛笔字的机器人 国产新科技亮相中博会 - 天天要闻

柔韧的手撕钢、会写毛笔字的机器人 国产新科技亮相中博会

6月27日,第二十届中国国际中小企业博览会在广州开幕。作为我国目前规模最大、规格最高、专门面向和服务中小企业的国际展会,这次来参会的企业可不一般,它们到底带来哪些与众不同的新技术新产品?这款钢材用手就能轻易弯曲、撕开,厚度只有A4纸的1/6,是生产高端电子产品的重要原材料。参展商 杨寒琳:之前主要依赖进口,...
3C标识充电宝新规落地:十家核心概念股深度解析 - 天天要闻

3C标识充电宝新规落地:十家核心概念股深度解析

2025年6月28日,民航局关于禁止无3C标识充电宝登机的新规正式生效,这一政策犹如行业洗牌的发令枪,瞬间激活了充电宝产业链的替代需求。据真锂研究院数据,全国90%存量充电宝面临淘汰,预计释放超500亿元市场空间。
雷军说特斯拉确实了不起:引领了行业趋势 尤其是FSD - 天天要闻

雷军说特斯拉确实了不起:引领了行业趋势 尤其是FSD

站长之家(ChinaZ.com)6月28日 消息:今日午间,小米汽车创始人雷军在社交媒体上公开发文,对特斯拉表达了高度赞赏。他提到:“特斯拉确实了不起,在很多领域引领了行业趋势,尤其是其FSD(全自动驾驶)技术。我们还要继续学习!”雷军的这番言论不仅表达了对特斯拉技术实力的认可,更在博文结尾特意配发了三个竖起的大拇指表...
看深圳福田创新实践 ,“一馆一策”构建公共文化服务新范式 - 天天要闻

看深圳福田创新实践 ,“一馆一策”构建公共文化服务新范式

6月26日,深圳市福田区公共文化服务“一馆一策”启动暨舞蹈主题馆“市民艺校”招生发布活动举行。本次活动是福田区公共文化服务“一馆一策”改革探索的落地,标志着福田区在深化公共文化服务供给侧改革、创新文化场馆运营机制方面迈出关键一步。多元主体共建文化新生态公共文化服务体系建设已成为文化改革的重要组成部分。...
又一关键突破,我国商用堆产镥-177 同位素正式供应市场 - 天天要闻

又一关键突破,我国商用堆产镥-177 同位素正式供应市场

IT之家 6 月 28 日消息,中核集团宣布,6 月 25 日,我国首个同位素生产技术品牌“和福一号”项目再次传来喜讯:经三批次辐照提纯与试用验证,中核集团秦山核电基地依托商用重水堆生产的镥-177 正式供应市场,年辐照产能超万居里,可完全满足全国市场需求。据悉,这标志着我国继碳-14 规模化供应、钇-90 具备规模化辐照生产...