1、面試場景與面試技巧
金三銀四招聘季,一位粉絲朋友最近在螞蟻金服第二輪面試時遇到這樣一個問題:若是MQ消費遇到瓶頸時該如何處理?。java
橫向擴容,相比不少讀者與我這位朋友同樣會脫口而出,面試官顯然不會滿意這樣的回答,而後追問道:橫向擴容是堆機器,還有沒有其餘辦法呢?面試
在面試過程當中,我的建議你們在聽到問題後稍做思考,不要立馬給出太直接的答案,而是應該與面試官進行探討,一方面可更深入的理解面試官的出題初衷,同時能夠給本身梳理一下思路。shell
消費端遇到瓶頸,這是一個結果,但引發這個結果的緣由是什麼呢?在沒有弄清楚緣由以前談優化、解決方案都會顯得很蒼白。數據庫
在這樣的面試場景中,咱們該如何探討交流呢?個人思路以下:後端
- 嘗試與面試官探討如何判斷消費端遇到瓶頸
- 如何查找根因
- 提出解決方案
> 舒適提示:爲了本文觀點的嚴謹性,本文主要以RocketMQ爲例進行剖析。性能優化
2、如何判斷消費端遇到瓶頸
在RocketMQ消費領域中判斷消費端遇到瓶頸一般有兩個重要的指標:運維
- 消息積壓數量(延遲數量)
- lastConsumeTime
在開源版本的控制檯rocketmq-console界面中,能夠查閱一個消費端上述兩個指標,以下圖所示: 異步
- Delay:消息積壓數量,即消費端還剩下多少消息未處理,該值越大,說明消費端遇到瓶頸了。
- LastConsumeTime:表示上一次成功消費的消息的存儲時間,該值離當前時間越大,一樣能說明消費端遇到瓶頸了。
那爲何會積壓呢?消費端是在哪遇到瓶頸了呢?性能
3、如何定位問題
消費端出現瓶頸,如何識別是客戶端的問題仍是服務端的問題,一個最簡單的辦法是看集羣內其餘消費組是否也有積壓,特別是和有問題的消費組訂閱同一個主題的其餘消費組是否有積壓,按照筆者的經驗,出現消息積壓一般是客戶端的問題,能夠經過查詢 rocketmq_client.log加以證實:優化
grep "flow" rocketmq_client.log
出現so do flow control 這樣的日誌,說明觸發了消費的限流,其直接觸發緣由:就是消息消費端積壓消息,即消費端沒法消費已拉取的消息,爲了不內存泄露,RocketMQ在消費端沒有將消息處理完成後,不會繼續向服務端拉取消息,並打印上述日誌。
那如何定位消費端慢在哪呢?是卡在哪行代碼呢?
一般的排查方法是跟蹤線程棧,即利用jstack命令查看線程運行狀況,以此來探究線程的運行狀況。
一般使用的命令以下:
ps -ef | grep java jstack pid > j1.log
一般爲了對比,我通常會連續打印5個文件,從而能夠在5個文件中查看同一個消費者線程,其狀態是否變化,若是未變化,則說明該線程卡主,那就是咱們重點須要關注的地方。
在RocketMQ中,消費端線程以ConsumeMessageThread_開頭,經過對線程的判斷,以下代碼讓人爲之興奮: 消費端線程的狀態是RUNNABLE,但在5個文件中其狀態都是同樣,基本能夠判定線程卡在具體的代碼,從示例代碼中是卡在掉一個外部的http藉口,從而加以解決,一般在涉及外部調用,特別是http調用,能夠設置一個超時時間,避免長時間等待。
四、解決方案
其實根據第三步驟,大機率能明確是哪一個地方慢,遇到了性能瓶頸,一般無非就是調第三方服務,數據庫等問題出現了瓶頸,而後對症下藥。數據庫等性能優化,並不在本文的討論範圍以內,故這裏能夠點到爲止,固然面試官後續可能會繼續聊數據庫優化等話題,這樣就實現了與面試官的交流互動,一環扣一環,技術交流氛圍友好,面試經過率大大提升。
最後,我還想和你們探討一個問題,出現消息積壓就必定意味着遇到消費瓶頸,必定須要處理嗎?
其實也否則,咱們回想一下爲何須要使用MQ,不就是利用異步解耦與削峯填谷嗎?例如在雙十一期間,大量突發流量匯入,此時極可能致使消息積壓,這正式咱們的用意,用MQ抗住突發流量,後端應用慢慢消費,保證消費端的穩定,在積壓的狀況下,若是tps正常,即問題不大,這個時候一般的處理方式就是橫向擴容,儘量的下降積壓,減小業務的延遲。
本文就介紹到這裏了。若是你們對RocketMQ感興趣,可下載個人電子書,獲取線上環境運維千億級消息流轉集羣的運維實戰經驗。 關注公衆號[中間件興趣圈],回覆RMQPDF便可獲取。