面試大殺器:消息中間件如何實(shí)現(xiàn)消費(fèi)吞吐量的百倍優(yōu)化咐熙?

目錄

(1)前請?zhí)崾?/p>

(2)unack消息的積壓問題

(3)如何解決unack消息的積壓問題

(4)高并發(fā)場景下的內(nèi)存溢出問題

(5)低吞吐量問題

(6)合理設(shè)置prefetch count

(7)階段性總結(jié)

1樟遣、前情提示

上一篇文章:互聯(lián)網(wǎng)面試必殺:如何保證消息中間件全鏈路數(shù)據(jù)100%不丟失(2)而叼,我們分析了ack機(jī)制的底層實(shí)現(xiàn)原理(delivery tag機(jī)制),還有消除處理失敗時(shí)的nack機(jī)制如何觸發(fā)消息重發(fā)豹悬。

通過這個(gè)葵陵,已經(jīng)讓大家進(jìn)一步對消費(fèi)端保證數(shù)據(jù)不丟失的方案的理解更進(jìn)一層了。

這篇文章瞻佛,我們將會對ack底層的delivery tag機(jī)制進(jìn)行更加深入的分析脱篙,讓大家理解的更加透徹一些。

面試時(shí)伤柄,如果被問到消息中間件數(shù)據(jù)不丟失問題的時(shí)候绊困,可以更深入到底層,給面試官進(jìn)行分析适刀。

2秤朗、unack消息的積壓問題

首先,我們要給大家介紹一下RabbitMQ的prefetch count這個(gè)概念笔喉。

大家看過上篇文章之后應(yīng)該都知道了取视,對每個(gè)channel(其實(shí)對應(yīng)了一個(gè)消費(fèi)者服務(wù)實(shí)例硝皂,你大體可以這么來認(rèn)為),RabbitMQ投遞消息的時(shí)候作谭,都是會帶上本次消息投遞的一個(gè)delivery tag的稽物,唯一標(biāo)識一次消息投遞。

然后折欠,我們進(jìn)行ack時(shí)贝或,也會帶上這個(gè)delivery tag,基于同一個(gè)channel進(jìn)行ack锐秦,ack消息里會帶上delivery tag讓RabbitMQ知道是對哪一次消息投遞進(jìn)行了ack咪奖,此時(shí)就可以對那條消息進(jìn)行刪除了。

大家先來看一張圖酱床,幫助大家回憶一下這個(gè)delivery tag的概念赡艰。

所以大家可以考慮一下,對于每個(gè)channel而言(你就認(rèn)為是針對每個(gè)消費(fèi)者服務(wù)實(shí)例吧斤葱,比如一個(gè)倉儲服務(wù)實(shí)例),其實(shí)都有一些處于unack狀態(tài)的消息揖闸。

比如RabbitMQ正在投遞一條消息到channel揍堕,此時(shí)消息肯定是unack狀態(tài)吧?

然后倉儲服務(wù)接收到一條消息以后汤纸,要處理這條消息需要耗費(fèi)時(shí)間衩茸,此時(shí)消息肯定是unack狀態(tài)吧?

同時(shí)贮泞,即使你執(zhí)行了ack之后楞慈,你要知道這個(gè)ack他默認(rèn)是異步執(zhí)行的,尤其如果你開啟了批量ack的話啃擦,更是有一個(gè)延遲時(shí)間才會ack的囊蓝,此時(shí)消息也是unack吧?

那么大家考慮一下令蛉,RabbitMQ他能夠無限制的不停給你的消費(fèi)者服務(wù)實(shí)例推送消息嗎聚霜?

明顯是不能的,如果RabbitMQ給你的消費(fèi)者服務(wù)實(shí)例推送的消息過多過快珠叔,比如都有幾千條消息積壓在某個(gè)消費(fèi)者服務(wù)實(shí)例的內(nèi)存中蝎宇。

那么此時(shí)這幾千條消息都是unack的狀態(tài),一直積壓著祷安,是不是有可能會導(dǎo)致消費(fèi)者服務(wù)實(shí)例的內(nèi)存溢出姥芥?內(nèi)存消耗過大?甚至內(nèi)存泄露之類的問題產(chǎn)生汇鞭?

所以說凉唐,RabbitMQ是必須要考慮一下消費(fèi)者服務(wù)的處理能力的庸追。

大家看看下面的圖,感受一下如果消費(fèi)者服務(wù)實(shí)例的內(nèi)存中積壓消息過多熊榛,都是unack的狀態(tài)锚国,此時(shí)會怎么樣。

3玄坦、如何解決unack消息的積壓問題

正是因?yàn)檫@個(gè)原因血筑,RabbitMQ基于一個(gè)prefetch count來控制這個(gè)unack message的數(shù)量。

你可以通過 “channel.basicQos(10)” 這個(gè)方法來設(shè)置當(dāng)前channel的prefetch count煎楣。

舉個(gè)例子豺总,比如你要是設(shè)置為10的話,那么意味著當(dāng)前這個(gè)channel里择懂,unack message的數(shù)量不能超過10個(gè)喻喳,以此來避免消費(fèi)者服務(wù)實(shí)例積壓unack message過多。

這樣的話困曙,就意味著RabbitMQ正在投遞到channel過程中的unack message表伦,以及消費(fèi)者服務(wù)在處理中的unack message,以及異步ack之后還沒完成ack的unack message慷丽,所有這些message加起來蹦哼,一個(gè)channel也不能超過10個(gè)。

如果你要簡單粗淺的理解的話要糊,也大致可以理解為這個(gè)prefetch count就代表了一個(gè)消費(fèi)者服務(wù)同時(shí)最多可以獲取多少個(gè)message來處理纲熏。所以這里也點(diǎn)出了prefetch這個(gè)單詞的意思。

prefetch就是預(yù)抓取的意思锄俄,就意味著你的消費(fèi)者服務(wù)實(shí)例預(yù)抓取多少條message過來處理局劲,但是最多只能同時(shí)處理這么多消息。

如果一個(gè)channel里的unack message超過了prefetch count指定的數(shù)量奶赠,此時(shí)RabbitMQ就會停止給這個(gè)channel投遞消息了鱼填,必須要等待已經(jīng)投遞過去的消息被ack了,此時(shí)才能繼續(xù)投遞下一個(gè)消息毅戈。

老規(guī)矩剔氏,給大家上一張圖,我們一起來看看這個(gè)東西是啥意思竹祷。

4谈跛、高并發(fā)場景下的內(nèi)存溢出問題

好!現(xiàn)在大家對ack機(jī)制底層的另外一個(gè)核心機(jī)制:prefetch機(jī)制也有了一個(gè)深刻的理解了塑陵。

此時(shí)感憾,咱們就應(yīng)該來考慮一個(gè)問題了。就是如何來設(shè)置這個(gè)prefetch count呢?這個(gè)東西設(shè)置的過大或者過小有什么影響呢阻桅?

其實(shí)大家理解了上面的圖就很好理解這個(gè)問題了凉倚。

假如說我們把prefetch count設(shè)置的很大,比如說3000嫂沉,5000稽寒,甚至100000,就這樣特別大的值趟章,那么此時(shí)會如何呢杏糙?

這個(gè)時(shí)候,在高并發(fā)大流量的場景下蚓土,可能就會導(dǎo)致消費(fèi)者服務(wù)的內(nèi)存被快速的消耗掉宏侍。

因?yàn)榧偃缯f現(xiàn)在MQ接收到的流量特別的大,每秒都上千條消息蜀漆,而且此時(shí)你的消費(fèi)者服務(wù)的prefetch count還設(shè)置的特別大谅河,就會導(dǎo)致可能一瞬間你的消費(fèi)者服務(wù)接收到了達(dá)到prefetch count指定數(shù)量的消息。

打個(gè)比方确丢,比如一下子你的消費(fèi)者服務(wù)內(nèi)存里積壓了10萬條消息绷耍,都是unack的狀態(tài),反正你的prefetch count設(shè)置的是10萬鲜侥。

那么對一個(gè)channel锨天,RabbitMQ就會最多容忍10萬個(gè)unack狀態(tài)的消息,在高并發(fā)下也就最多可能積壓10萬條消息在消費(fèi)者服務(wù)的內(nèi)存里剃毒。

那么此時(shí)導(dǎo)致的結(jié)果,就是消費(fèi)者服務(wù)直接被擊垮了搂赋,內(nèi)存溢出赘阀,OOM,服務(wù)宕機(jī)脑奠,然后大量unack的消息會被重新投遞給其他的消費(fèi)者服務(wù)基公,此時(shí)其他消費(fèi)者服務(wù)一樣的情況,直接宕機(jī)宋欺,最后造成雪崩效應(yīng)轰豆。

所有的消費(fèi)者服務(wù)因?yàn)榭覆蛔∵@么大的數(shù)據(jù)量,全部宕機(jī)齿诞。

大家來看看下面的圖酸休,自己感受一下現(xiàn)場的氛圍。

5祷杈、低吞吐量問題

那么如果反過來呢斑司,我們要是把prefetch count設(shè)置的很小會如何呢?

比如說我們把prefetch count設(shè)置為1但汞?此時(shí)就必然會導(dǎo)致消費(fèi)者服務(wù)的吞吐量極低宿刮。因?yàn)槟慵词固幚硗暌粭l消息互站,執(zhí)行ack了也是異步的。

給你舉個(gè)例子僵缺,假如說你的prefetch count = 1胡桃,RabbitMQ最多投遞給你1條消息處于unack狀態(tài)。

此時(shí)比如你剛處理完這條消息磕潮,然后執(zhí)行了ack的那行代碼翠胰,結(jié)果不幸的是,ack需要異步執(zhí)行揉抵,也就是需要100ms之后才會讓RabbitMQ感知到亡容。

那么100ms之后RabbitMQ感知到消息被ack了,此時(shí)才會投遞給你下一條消息冤今!

這就尷尬了闺兢,在這100ms期間,你的消費(fèi)者服務(wù)是不是啥都沒干跋钒铡屋谭?

這不就直接導(dǎo)致了你的消費(fèi)者服務(wù)處理消息的吞吐量可能下降10倍,甚至百倍龟糕,千倍桐磁,都有這種可能!

大家看看下面的圖讲岁,感受一下低吞吐量的現(xiàn)場我擂。

6、合理的設(shè)置prefetch count

所以鑒于上面兩種極端情況缓艳,RabbitMQ官方給出的建議是prefetch count一般設(shè)置在100~300之間校摩。

也就是一個(gè)消費(fèi)者服務(wù)最多接收到100~300個(gè)message來處理,允許處于unack狀態(tài)阶淘。

這個(gè)狀態(tài)下可以兼顧吞吐量也很高衙吩,同時(shí)也不容易造成內(nèi)存溢出的問題。

但是其實(shí)在我們的實(shí)踐中溪窒,這個(gè)prefetch count大家完全是可以自己去壓測一下的坤塞。

比如說慢慢調(diào)節(jié)這個(gè)值,不斷加大澈蚌,觀察高并發(fā)大流量之下摹芙,吞吐量是否越來越大,而且觀察消費(fèi)者服務(wù)的內(nèi)存消耗宛瞄,會不會OOM瘫辩、頻繁FullGC等問題。

7、階段性總結(jié)

其實(shí)通過最近幾篇文章伐厌,基本上已經(jīng)把消息中間件的消費(fèi)端如何保證數(shù)據(jù)不丟失這個(gè)問題剖析的較為深入和透徹了承绸。

如果你是基于RabbitMQ來做消息中間件的話,消費(fèi)端的代碼里挣轨,必須考慮三個(gè)問題:手動ack军熏、處理失敗的nack、prefetch count的合理設(shè)置

這三個(gè)問題背后涉及到了各種機(jī)制:

自動ack機(jī)制

delivery tag機(jī)制

ack批量與異步提交機(jī)制

消息重發(fā)機(jī)制

手動nack觸發(fā)消息重發(fā)機(jī)制

prefetch count過大導(dǎo)致內(nèi)存溢出問題

prefetch count過小導(dǎo)致吞吐量過低

這些底層機(jī)制和問題卷扮,咱們都一步步分析清楚了荡澎。

所以到現(xiàn)在,單論消費(fèi)端這塊的數(shù)據(jù)不丟失技術(shù)方案晤锹,相信大家在面試的時(shí)候就可以有一整套自己的理解和方案可以闡述了摩幔。

end

如果對自己未來有想法,想提升自己鞭铆,你現(xiàn)在在JAVA這條路上掙扎或衡,也想在IT行業(yè)拿高薪,可以參加我們免費(fèi)的公開課試聽學(xué)習(xí) 干貨滿滿的车遂,選擇最適合自己的課程學(xué)習(xí)封断,技術(shù)大牛親授,課程內(nèi)容有:Java工程化舶担、高性能及分布式坡疼、高性能、深入淺出衣陶。高架構(gòu)柄瑰。性能調(diào)優(yōu)、Spring剪况,MyBatis教沾,Netty源碼分析和大數(shù)據(jù)等多個(gè)知識點(diǎn)。如果你想拿高薪的拯欧,想學(xué)習(xí)的,想就業(yè)前景好的财骨,想跟別人競爭能取得優(yōu)勢的镐作,想進(jìn)阿里面試但擔(dān)心面試不過的,你都可以來隆箩。

加群:810589193该贾,點(diǎn)擊鏈接加入群聊【Java架構(gòu)學(xué)習(xí)交流群】:https://jq.qq.com/?_wv=1027&k=5deQUBl

如有收獲,請幫忙轉(zhuǎn)發(fā)捌臊,您的鼓勵(lì)是作者最大的動力杨蛋,謝謝!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市逞力,隨后出現(xiàn)的幾起案子曙寡,更是在濱河造成了極大的恐慌,老刑警劉巖寇荧,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件举庶,死亡現(xiàn)場離奇詭異,居然都是意外死亡揩抡,警方通過查閱死者的電腦和手機(jī)户侥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來峦嗤,“玉大人蕊唐,你說我怎么就攤上這事∷干瑁” “怎么了替梨?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長署尤。 經(jīng)常有香客問我耙替,道長,這世上最難降的妖魔是什么曹体? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任俗扇,我火速辦了婚禮,結(jié)果婚禮上箕别,老公的妹妹穿的比我還像新娘铜幽。我一直安慰自己,他們只是感情好串稀,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布除抛。 她就那樣靜靜地躺著,像睡著了一般母截。 火紅的嫁衣襯著肌膚如雪到忽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天清寇,我揣著相機(jī)與錄音喘漏,去河邊找鬼。 笑死华烟,一個(gè)胖子當(dāng)著我的面吹牛翩迈,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播盔夜,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼负饲,長吁一口氣:“原來是場噩夢啊……” “哼堤魁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起返十,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤妥泉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后吧慢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體涛漂,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年检诗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了匈仗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,625評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡逢慌,死狀恐怖悠轩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情攻泼,我是刑警寧澤火架,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站忙菠,受9級特大地震影響何鸡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜牛欢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一骡男、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧傍睹,春花似錦隔盛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至访得,卻和暖如春龙亲,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背悍抑。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工鳄炉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人传趾。 一個(gè)月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓迎膜,卻偏偏與公主長得像泥技,于是被迫代替她去往敵國和親浆兰。 傳聞我的和親對象是個(gè)殘疾皇子磕仅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 應(yīng)用場景 異步處理 場景說明:用戶注冊后,需要發(fā)注冊郵件和注冊短信簸呈,傳統(tǒng)的做法有兩種: 1.串行的方式 2.并行的...
    lijun_m閱讀 1,813評論 0 3
  • 什么叫消息隊(duì)列 消息(Message)是指在應(yīng)用間傳送的數(shù)據(jù)榕订。消息可以非常簡單,比如只包含文本字符串蜕便,也可以更復(fù)雜...
    lijun_m閱讀 1,340評論 0 1
  • 本文大綱 RabbitMQ 歷史 RabbitMQ 應(yīng)用場景 RabbitMQ 系統(tǒng)架構(gòu) RabbitMQ 基本概...
    Java_Explorer閱讀 16,318評論 1 40
  • 利用RabbitMQ集群橫向擴(kuò)展能力劫恒,均衡流量壓力,讓消息集群的秒級服務(wù)能力達(dá)到百萬轿腺,Google曾做過此類實(shí)驗(yàn)两嘴;...
    有貨技術(shù)閱讀 3,455評論 0 1
  • 早上分享:巜世上最有能量的語言,一定要經(jīng)常說族壳!》 1憔辫、能控制住對方發(fā)火的語言: 對不起! 2仿荆、筑起謙虛人格塔的語言...
    y詩淇閱讀 164評論 0 0