一次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 具備規模化輻照生產...