新聞中心
1、問題現(xiàn)象
先說明下RocketMQ版本, 4.6.0的老版本了。

成都創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都做網(wǎng)站、成都網(wǎng)站制作、成都外貿(mào)網(wǎng)站建設(shè)、中山網(wǎng)絡(luò)推廣、微信小程序、中山網(wǎng)絡(luò)營銷、中山企業(yè)策劃、中山品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);成都創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供中山建站搭建服務(wù),24小時(shí)服務(wù)熱線:18980820575,官方網(wǎng)址:www.cdcxhl.com
線下環(huán)境客戶端啟動(dòng)會(huì)頻繁報(bào)錯(cuò)響應(yīng)超時(shí),導(dǎo)致consumer實(shí)例化失敗,無法啟動(dòng)應(yīng)用。
圖片
2、排查
確認(rèn)線下環(huán)境RocketMQ集群流量、生產(chǎn)消費(fèi)數(shù)量無異常。
集群gc次數(shù)不多,但是耗時(shí)高。(原本監(jiān)控看板異常數(shù)據(jù)缺失,所以少了前面一段)
圖片
master節(jié)點(diǎn)cpu使用率、load極高。
圖片
升配,4c8g升級8c32g,擴(kuò)大jvm內(nèi)存。
系統(tǒng)指標(biāo)略有下降,但是客戶端異常沒有明顯改善。
只能進(jìn)一步排查根因,還得上arthas。
thread -n 3查看cpu高的線程在做什么。
發(fā)現(xiàn)兩個(gè)異常線程。
1)一個(gè)線程在執(zhí)行AdminBrokerProcessor.queryTopicConsumerByWho()。
圖片
這個(gè)是查詢Topic的conusmerGroup信息。
比較奇怪的是,這個(gè)請求很頻繁,后來發(fā)現(xiàn)是控制臺(tái)應(yīng)用dashboard有個(gè)定時(shí)任務(wù),30s查詢一次。
這個(gè)請求的耗時(shí)主要是在數(shù)組的遍歷處理上,說明內(nèi)存中的數(shù)據(jù)非常大。
圖片
而這個(gè)源碼中的offsetTable,就是RocketMQ中保存consumerGroup位點(diǎn)信息的對象。它的key是topic@group拼接的。
圖片
先臨時(shí)處理,把dashboard應(yīng)用關(guān)閉了,減少請求。但是效果并不明顯。
2)另一個(gè)線程在執(zhí)行定時(shí)任務(wù)ConsumerOffsetManager.persist()。
(線程調(diào)用信息忘記截圖了)
這個(gè)是RocketMQ集群持久化consumerGroup的offset信息的定時(shí)任務(wù)。
圖片
會(huì)將整個(gè)內(nèi)存對象轉(zhuǎn)化為jsonString寫入磁盤文件中。
這個(gè)內(nèi)存對象就是前面提到的offsetTable,就是RocketMQ中保存consumerGroup位點(diǎn)信息的對象。
這里消耗資源多,還是說明我們的內(nèi)存對象非常大。
因?yàn)槭蔷€下環(huán)境,可靠性要求不高。所以先臨時(shí)處理,把定時(shí)任務(wù)默認(rèn)配置5s改成50s,減少持久化次數(shù)。
效果顯著,機(jī)器cpu、負(fù)載都明顯改善。
好了,現(xiàn)在問題的矛頭都指向了這個(gè)offsetTable,那它到底有多大,為什么這么大?
3、定位根因
3.1 直接原因
大對象的定位,一般來說需要dump看看,不過這個(gè)對象有點(diǎn)特殊,剛剛也提到了它會(huì)被持久化到文件中,所以直接看文件大小和內(nèi)容就行了。
持久化文件的配置路徑,可以看下啟動(dòng)的conf.properties
storePathRootDir=/usr/local/rocketmq/store1
storePathCommitLog=/usr/local/rocketmq/store1/commitlog
storePathConsumerQueue=/usr/local/rocketmq/store1/consumequeue
storePathIndex=/usr/local/rocketmq/store1/index在/usr/local/rocketmq/store1目錄下找到config文件夾的consummerOffset.json文件,44M,amazing~
對一個(gè)幾十M的對象頻繁序列化和持久化,加上內(nèi)網(wǎng)磁盤比較差,難怪負(fù)載如此高。
圖片
(這里截圖是當(dāng)時(shí)應(yīng)急時(shí)備份的文件,新的文件目前是414K)
3.2 根本原因
為什么這個(gè)內(nèi)存對象這么大呢?
查看了下文件內(nèi)容,是RocketMQ中保存consumerGroup位點(diǎn)信息的對象,它的key是topic@group拼接的。
我們發(fā)現(xiàn)大量奇怪的consumerGroup name,跟一個(gè)topic聯(lián)合產(chǎn)生了幾千個(gè)key。
查看了下內(nèi)部封裝的客戶端代碼,找到了罪魁禍?zhǔn)住?/p>
圖片
線下環(huán)境會(huì)根據(jù)小環(huán)境(比如自己起的測試、單測環(huán)境、CI測試環(huán)境等)拼接一個(gè)獨(dú)立的consumerGroup name。
在線下,每次CI的測試環(huán)境名字會(huì)變化,所以導(dǎo)致consumerGroup name數(shù)量急劇膨脹。
4、優(yōu)化
問題找到了,直接的解決方式是刪除文件中無用的consumerGroup name,重啟broker進(jìn)行加載。
由于是線下環(huán)境,不需要擔(dān)心位點(diǎn)丟失的問題,同時(shí)當(dāng)客戶端請求時(shí)會(huì)自動(dòng)創(chuàng)建新的位點(diǎn)信息,所以可以考慮直接刪除。
圖片
先停止broker進(jìn)程(否則會(huì)自動(dòng)落盤內(nèi)存數(shù)據(jù),創(chuàng)建新的文件),然后重命名相關(guān)文件(用于備份回滾),重新啟動(dòng)broker進(jìn)程,讀取空文件加載空對象。
重啟后,各個(gè)客戶端在請求集群時(shí),會(huì)自動(dòng)創(chuàng)建訂閱關(guān)系和消費(fèi)位點(diǎn)記錄,負(fù)載略有升高,然后就恢復(fù)到較低的負(fù)載水位了。
24h的監(jiān)控顯示,優(yōu)化效果顯著,整個(gè)機(jī)器負(fù)載降低,請求讀寫耗時(shí)也顯著降低。
圖片
注意:保存訂閱關(guān)系的subscriptionGroup.json也存在同樣consumerGroup過多導(dǎo)致膨脹的問題,同樣的原因和優(yōu)化方式。默認(rèn)訂閱關(guān)系也是會(huì)自動(dòng)創(chuàng)建的。這里就不展開贅述了。
5、擴(kuò)展一下
如果類似的問題出在線上怎么辦?
事后來看,類似問題是能夠提前避免的,主要考慮兩個(gè)措施:
- 要做好持久化文件(對應(yīng)內(nèi)存對象)大小監(jiān)控,避免出現(xiàn)內(nèi)存大對象。如果發(fā)現(xiàn)異常增長,必須提前排查處理。
- 磁盤要足夠好,使用SSD是基本要求,避免頻繁刷盤導(dǎo)致負(fù)載升高。
文章標(biāo)題:消費(fèi)者太多!RocketMQ又炸了!
文章路徑:http://fisionsoft.com.cn/article/ccesees.html


咨詢
建站咨詢
