1、面試場景與面試技巧
金三銀四招聘季,一位粉絲朋友最近在螞蟻金服第二輪面試時遇到這樣一個問題:如果MQ消費遇到瓶頸時該如何處理?。
橫向擴容,相比很多讀者與我這位朋友一樣會脫口而出,面試官顯然不會滿意這樣的回答,然後追問道:橫向擴容是堆機器,還有沒有其他辦法呢
在面試過程中,個人建議大家在聽到問題後稍作思考,不要立馬給出太直接的答案,而是應該與面試官進行探討,一方面可更深刻的理解面試官的出題初衷,同時可以給自己梳理一下思路。
消費端遇到瓶頸,這是一個結果,但引起這個結果的原因是什麼呢?在沒有弄清楚原因之前談最佳化、解決方案都會顯得很蒼白。
在這樣的面試場景中,我們該如何探討交流呢?我的思路如下:
嘗試與面試官探討如何判斷消費端遇到瓶頸如何查詢根因 提出解決方案溫馨提示:為了本文觀點的嚴謹性,本文主要以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呼叫,可以設定一個超時時間,避免長時間等待。
4、解決方案其實根據第三步驟,大機率能明確是哪個地方慢,遇到了效能瓶頸,通常無非就是調第三方服務,資料庫等問題出現了瓶頸,然後對症下藥。資料庫等效能最佳化,並不在本文的討論範圍之內,故這裡可以點到為止,當然面試官後續可能會繼續聊資料庫最佳化等話題,這樣就實現了與面試官的交流互動,一環扣一環,技術交流氛圍友好,面試透過率大大提高。
最後,我還想和大家探討一個問題,**出現訊息積壓就一定意味著遇到消費瓶頸**,一定需要處理嗎?
其實也不然,我們回想一下為什麼需要使用MQ,不就是利用非同步解耦與削峰填谷嗎?例如在雙十一期間,大量突發流量匯入,此時很可能導致訊息積壓,這正是我們的用意,用MQ抗住突發流量,後端應用慢慢消費,保證消費端的穩定,在積壓的情況下,如果tps正常,即問題不大,這個時候通常的處理方式就是橫向擴容,儘可能地降低積壓,減少業務的延遲。
本文就介紹到這裡了。如果大家對RocketMQ感興趣,可以下載我的電子書。