如果你的簡(jiǎn)歷上寫(xiě)了熟練掌握消息隊(duì)列,那么這是一個(gè)非常容易被問(wèn)到的問(wèn)題,同時(shí)也是一個(gè)非?,F(xiàn)實(shí)的問(wèn)題,很有可能一不小心就被你遇到了。
今天我們就來(lái)聊一聊,一旦真的遇到了這個(gè)問(wèn)題,需要如何去分析解決?
一般而言,出現(xiàn)消息積壓有2個(gè)方面的原因:
1、從生產(chǎn)者的角度來(lái)說(shuō): 可能是業(yè)務(wù)迅速增長(zhǎng),導(dǎo)致生產(chǎn)者在短時(shí)間內(nèi)生成大量消息,而下游消費(fèi)者的處理能力無(wú)法滿足,從而導(dǎo)致消息積壓。
2、從消費(fèi)者的角度來(lái)說(shuō): 大概率是消費(fèi)者遇到了一些問(wèn)題,導(dǎo)致無(wú)法及時(shí)處理消息。這常見(jiàn)于下游消費(fèi)邏輯中的遠(yuǎn)程調(diào)用出現(xiàn)大量超時(shí)、Redis或數(shù)據(jù)庫(kù)發(fā)生故障(上次B佬遇到的就是這個(gè)問(wèn)題)等情況。
很明顯,業(yè)務(wù)迅速增長(zhǎng)是可遇而不可求的事(常見(jiàn)于營(yíng)銷活動(dòng)、秒殺等場(chǎng)景),不可能要求生產(chǎn)者少發(fā)送消息,所以遇到這個(gè)問(wèn)題只能從消費(fèi)者的角度尋求解決方案。
一般來(lái)說(shuō),解決消息積壓有如下幾個(gè)常見(jiàn)方案:
增加消費(fèi)者數(shù)量: 如果消息消費(fèi)者的處理速度無(wú)法滿足消息產(chǎn)生的速度,可以通過(guò)增加消費(fèi)者數(shù)量來(lái)提高消費(fèi)能力。這樣可以將負(fù)載分散到多個(gè)消費(fèi)者上,加快消息處理速度,減少積壓。不過(guò)需要注意的是,一般消息隊(duì)列都有分區(qū)的概念,消費(fèi)者的數(shù)量是不能超過(guò)分區(qū)的數(shù)量。
增加消息隊(duì)列的容量: 如果消息隊(duì)列的容量設(shè)置過(guò)小,可能會(huì)導(dǎo)致消息積壓。可以通過(guò)增加消息隊(duì)列的容量來(lái)緩解積壓?jiǎn)栴}。但需要注意,過(guò)大的消息隊(duì)列容量可能會(huì)增加消息處理的延遲。
優(yōu)化消息消費(fèi)的邏輯: 檢查消息消費(fèi)邏輯是否存在性能瓶頸或不必要的復(fù)雜計(jì)算。優(yōu)化消息消費(fèi)的邏輯可以提高消費(fèi)速度,減少消息積壓。
設(shè)置消息消費(fèi)失敗的處理機(jī)制: 當(dāng)消息消費(fèi)失敗時(shí),可以根據(jù)業(yè)務(wù)需求選擇合適的處理方式。可以將失敗的消息記錄下來(lái),后續(xù)再次消費(fèi);或者將失敗的消息發(fā)送到死信隊(duì)列進(jìn)行處理。
監(jiān)控和報(bào)警機(jī)制:建立監(jiān)控和報(bào)警機(jī)制,及時(shí)發(fā)現(xiàn)消息積壓的情況并采取相應(yīng)的措施。可以通過(guò)監(jiān)控指標(biāo)、日志或?qū)I(yè)的監(jiān)控工具來(lái)實(shí)現(xiàn)。
不過(guò)上面的解決方案還是偏于理論了,一旦線上已經(jīng)產(chǎn)生了大量的消息積壓,該如何迅速處理呢?
在實(shí)際實(shí)現(xiàn)中,可以按照如下步驟快速處理消息積壓?jiǎn)栴}:
確認(rèn)并解決消費(fèi)端的bug: 保證消費(fèi)端能夠正常處理消息。
停止所有消費(fèi)端: 新建一個(gè)Topic,將Partition分區(qū)數(shù)量調(diào)整為原來(lái)的10倍。
編寫(xiě)數(shù)據(jù)分發(fā)的Consumer程序: 該程序?qū)iT消費(fèi)積壓的數(shù)據(jù),不做處理,直接將數(shù)據(jù)寫(xiě)入臨時(shí)創(chuàng)建的Topic的10個(gè)Partition中。(可以參考我在DDD專欄中基于Disruptor的分發(fā)組件來(lái)實(shí)現(xiàn))
臨時(shí)增加10倍的消費(fèi)者節(jié)點(diǎn): 重新部署Consumer,訂閱新創(chuàng)建的臨時(shí)Topic,用以快速處理臨時(shí)Partition分區(qū)數(shù)據(jù)。
通過(guò)上述方法,可以迅速處理積壓的消息。待積壓消息處理完成后,再將系統(tǒng)恢復(fù)為原有部署架構(gòu),釋放臨時(shí)創(chuàng)建的Topic和相應(yīng)的機(jī)器資源。