消息隊(duì)列總結(jié)

##背景:做部門技術(shù)分享時(shí)邮偎,學(xué)習(xí)整理了消息隊(duì)列管跺。

一、應(yīng)用場(chǎng)景

消息隊(duì)列中間件是分布式系統(tǒng)中重要的組件禾进。主要解決 異步消息豁跑、應(yīng)用耦合、流量削鋒泻云、日志收集 等問題艇拍,實(shí)現(xiàn)高性能,高可用宠纯,可伸縮和最終一致性架構(gòu)卸夕。


異步處理? 場(chǎng)景:用戶注冊(cè)后,需要發(fā)注冊(cè)郵件和短信婆瓜。

傳統(tǒng)的做法有兩種:a) 串行的方式快集;b) 并行方式贡羔。

a) 串行方式:將注冊(cè)信息寫入數(shù)據(jù)庫(kù)成功后,發(fā)送注冊(cè)郵件个初,再發(fā)送注冊(cè)短信乖寒。

以上三個(gè)任務(wù)全部完成后,返回給客戶端院溺。

串行方式

b) 并行方式:將注冊(cè)信息寫入數(shù)據(jù)庫(kù)成功后楣嘁,發(fā)送注冊(cè)郵件的同時(shí),發(fā)送注冊(cè)短信珍逸。

以上三個(gè)任務(wù)完成后逐虚,返回給客戶端。

串行方式

兩種方式對(duì)比:假設(shè)三個(gè)業(yè)務(wù)節(jié)點(diǎn)每個(gè)使用50毫秒鐘弄息,不考慮網(wǎng)絡(luò)等其他開銷痊班。由于CPU在單位時(shí)間內(nèi)處理的請(qǐng)求數(shù)是一定的,假設(shè)CPU 1秒內(nèi)吞吐量是100次摹量。

1涤伐、串行方式的執(zhí)行時(shí)間是150毫秒,并行的時(shí)間是100毫秒缨称。

2凝果、串行方式1秒內(nèi)CPU可處理的請(qǐng)求量是7次(1000/150)

3、并行方式處理的請(qǐng)求量是10次(1000/100)

引入消息隊(duì)列睦尽,將不是必須的業(yè)務(wù)邏輯器净,異步處理。改造后的架構(gòu)如下:

應(yīng)用消息隊(duì)列

1当凡、用戶的響應(yīng)時(shí)間55毫秒山害。

2、系統(tǒng)的吞吐量提高到每秒20 QPS沿量,比串行提高了3倍浪慌,比并行提高了2倍。


應(yīng)用解耦? 場(chǎng)景:用戶下單后朴则,訂單系統(tǒng)需要通知庫(kù)存系統(tǒng)权纤。

傳統(tǒng)的做法是,訂單系統(tǒng)調(diào)用庫(kù)存系統(tǒng)的接口乌妒。如下圖:

傳統(tǒng)方式

傳統(tǒng)模式的缺點(diǎn):

1汹想、假如庫(kù)存系統(tǒng)無(wú)法訪問,則訂單減庫(kù)存將失敗撤蚊,從而導(dǎo)致訂單失敗古掏。

2、訂單系統(tǒng)與庫(kù)存系統(tǒng)存在依賴侦啸。

引入消息隊(duì)列槽唾,改進(jìn)后架構(gòu)如下:

引入消息隊(duì)列

訂單系統(tǒng):用戶下單后席镀,完成持久化處理,將消息寫入消息隊(duì)列夏漱,返回用戶訂單成功。

庫(kù)存系統(tǒng):訂閱下單的消息顶捷,采用拉/推的方式挂绰,獲取下單信息,進(jìn)行庫(kù)存操作服赎。

1葵蒂、假如在下單時(shí)庫(kù)存系統(tǒng)不能正常使用,也不影響正常下單重虑。因?yàn)橄聠魏蠹叮唵蜗到y(tǒng)寫入消息隊(duì)列就不再關(guān)心其他的后續(xù)操作了。

2缺厉、實(shí)現(xiàn)訂單系統(tǒng)與庫(kù)存系統(tǒng)的應(yīng)用解耦永高。


流量削峰? 場(chǎng)景:秒殺活動(dòng),一般會(huì)因?yàn)榱髁窟^大提针,導(dǎo)致流量暴增命爬,應(yīng)用掛掉。

為解決這個(gè)問題辐脖,一般需要在應(yīng)用前端加入消息隊(duì)列饲宛。用戶的請(qǐng)求,服務(wù)器接收后嗜价,首先寫入消息隊(duì)列艇抠。假如消息隊(duì)列長(zhǎng)度超過最大數(shù)量,則直接拋棄用戶請(qǐng)求或跳轉(zhuǎn)到錯(cuò)誤頁(yè)面久锥,秒殺業(yè)務(wù)根據(jù)消息隊(duì)列中的請(qǐng)求信息家淤,再做后續(xù)處理。如圖:

流量削峰

1奴拦、可以控制活動(dòng)的人數(shù)媒鼓。

2、可以緩解短時(shí)間內(nèi)高流量壓垮應(yīng)用错妖。


日志處理? 場(chǎng)景:將消息隊(duì)列用在日志處理中绿鸣,比如Kafka,解決大量日志傳輸?shù)膯栴}暂氯。

日志收集

1潮模、日志采集客戶端,負(fù)責(zé)日志數(shù)據(jù)采集痴施,定時(shí)寫受寫入Kafka隊(duì)列擎厢。

2究流、Kafka消息隊(duì)列,負(fù)責(zé)日志數(shù)據(jù)的接收动遭,存儲(chǔ)和轉(zhuǎn)發(fā)芬探。

3、日志處理應(yīng)用:訂閱并消費(fèi)kafka隊(duì)列中的日志數(shù)據(jù)厘惦。


二偷仿、兩種模式

消息隊(duì)列的兩種模式:點(diǎn)對(duì)點(diǎn)、發(fā)布訂閱宵蕉。

p2p(點(diǎn)對(duì)點(diǎn))包含三個(gè)角色:消息隊(duì)列(Queue)酝静、發(fā)送者(Sender)、接收者(Receiver)

p2p

1羡玛、每個(gè)消息都被發(fā)送到一個(gè)特定的隊(duì)列别智,接收者從隊(duì)列中獲取消息。

2稼稿、隊(duì)列保留著消息薄榛,直到他們被消費(fèi)或超時(shí)。

P2P模式的特點(diǎn):

1让歼、每個(gè)消息只有一個(gè)消費(fèi)者(Consumer)(即一旦被消費(fèi)蛇数,消息就不再在消息隊(duì)列中)。

2是越、發(fā)送者和接收者之間在時(shí)間上沒有依賴性耳舅。

Pub/Sub(發(fā)布訂閱)包含三個(gè)角色:主題(Topic)、發(fā)布者(Publisher)倚评、訂閱者(Subscriber)

Pub/Sub

1浦徊、多個(gè)發(fā)布者將消息發(fā)送到Topic,系統(tǒng)將這些消息傳遞給多個(gè)訂閱者天梧。

Pub/Sub的特點(diǎn):

1盔性、每個(gè)消息可以有多個(gè)消費(fèi)者。

2呢岗、發(fā)布者和訂閱者之間有時(shí)間上的依賴性冕香。

3、為了消費(fèi)消息后豫,訂閱者必須保持運(yùn)行的狀態(tài)悉尾。


三、組成部分

幾個(gè)重要概念

Producer:消息生產(chǎn)者挫酿,就是投遞消息的程序构眯。

Broker:消息隊(duì)列服務(wù)器實(shí)體。

Consumer:消息消費(fèi)者早龟,就是接受消息的程序惫霸。

Queue:消息隊(duì)列載體猫缭,每個(gè)消息都會(huì)被投入到一個(gè)或多個(gè)隊(duì)列。

消息隊(duì)列邏輯結(jié)構(gòu)如下壹店,其中中間是queue猜丹。(實(shí)際載體為broker)

邏輯結(jié)構(gòu)


消息隊(duì)列的本質(zhì):兩次RPC加一次轉(zhuǎn)儲(chǔ)

消息隊(duì)列

1、RPC通信協(xié)議:負(fù)載均衡硅卢、服務(wù)發(fā)現(xiàn)居触、通信協(xié)議、序列化協(xié)議老赤。

2、高可用:依賴于RPC和存儲(chǔ)的高可用來(lái)做的制市。

3抬旺、服務(wù)端承載消息堆積的能力(依賴4)

a) 為了滿足錯(cuò)峰/流控/最終可達(dá)等一系列需求,把消息存儲(chǔ)下來(lái)祥楣,然后選擇時(shí)機(jī)投遞开财;

b) 存儲(chǔ)可以做成很多方式。比如存儲(chǔ)在內(nèi)存里误褪,存儲(chǔ)在分布式KV里责鳍,存儲(chǔ)在磁盤里,存儲(chǔ)在數(shù)據(jù)庫(kù)里等等兽间。歸結(jié)起來(lái)历葛,主要有持久化和非持久化兩種。持久化的形式能更大程度地保證消息的可靠性(如斷電等不可抗外力)嘀略,并且理論上能承載更大限度的消息堆積(外存的空間遠(yuǎn)大于內(nèi)存)

4恤溶、存儲(chǔ)子系統(tǒng)選型:從速度來(lái)看,文件系統(tǒng)>分布式KV(持久化)>分布式文件系統(tǒng)>數(shù)據(jù)庫(kù)帜羊,可靠性截然相反咒程。

5、消費(fèi)關(guān)系選型

a) 解析發(fā)送接收關(guān)系讼育,進(jìn)行正確的消息投遞了帐姻;

b) 發(fā)送關(guān)系的維護(hù),發(fā)送關(guān)系變更時(shí)的通知奶段,如config server饥瓷、zookeeper等。


四痹籍、典型問題

順序有序:指的是可以按照消息的發(fā)送順序來(lái)消費(fèi)

例如:一筆訂單產(chǎn)生了 3 條消息扛伍,分別是訂單創(chuàng)建、訂單付款词裤、訂單完成刺洒。消費(fèi)時(shí)鳖宾,要按照順序依次消費(fèi)才有意義。與此同時(shí)多筆訂單之間又是可以并行消費(fèi)的逆航。示例:假如生產(chǎn)者產(chǎn)生了2條消息:M1鼎文、M2,要保證這兩條消息的順序因俐,應(yīng)該怎樣做拇惋?

保證消息有序,可能會(huì)采用的方法

假定M1發(fā)送到S1抹剩,M2發(fā)送到S2撑帖,如果要保證M1先于M2被消費(fèi),那么需要M1到達(dá)消費(fèi)端被消費(fèi)后澳眷,通知S2胡嘿,然后S2再將M2發(fā)送到消費(fèi)端。如果M1和M2分別發(fā)送到兩臺(tái)Server上钳踊,就不能保證M1先達(dá)到MQ集群衷敌,也不能保證M1被先消費(fèi)。換個(gè)角度看拓瞪,如果M2先于M1達(dá)到MQ集群缴罗,甚至M2被消費(fèi)后,M1才達(dá)到消費(fèi)端祭埂,這時(shí)消息也就亂序了面氓。說明以上模型是不能保證消息的順序的。

如何才能在MQ集群保證消息的順序蛆橡?

一種簡(jiǎn)單的方式就是將M1侧但、M2發(fā)送到同一個(gè)Server上:

為保證消息順序,改進(jìn)后的方法

這樣可以保證M1先于M2到達(dá)MQServer(生產(chǎn)者等待M1發(fā)送成功后再發(fā)送M2)航罗,根據(jù)先達(dá)到先被消費(fèi)的原則禀横,M1會(huì)先于M2被消費(fèi),這樣就保證了消息的順序粥血。這個(gè)模型也僅僅是理論上可以保證消息的順序柏锄,在實(shí)際場(chǎng)景中可能會(huì)遇到下面的問題:M1晚于M2到達(dá)消費(fèi)端。

網(wǎng)絡(luò)延遲問題

如果發(fā)送M1耗時(shí)大于發(fā)送M2的耗時(shí)复亏,那么M2就仍將被先消費(fèi)趾娃。即使M1和M2同時(shí)到達(dá)消費(fèi)端,由于2個(gè)消費(fèi)端負(fù)載不同缔御,仍然可能出現(xiàn)M2先消費(fèi)抬闷。

那如何解決這個(gè)問題?

將M1和M2發(fā)往同一個(gè)消費(fèi)者,且發(fā)送M1后笤成,需要消費(fèi)端響應(yīng)成功后才能發(fā)送M2评架。M1被發(fā)送到消費(fèi)端后,消費(fèi)端1沒有響應(yīng)炕泳,那是繼續(xù)發(fā)送M2呢纵诞,還是重新發(fā)送M1?一般為了保證消息一定被消費(fèi)培遵,肯定會(huì)選擇重發(fā)M1到另外一個(gè)消費(fèi)端2浙芙。

保證消息順序的正確姿勢(shì)

總結(jié)起來(lái),要實(shí)現(xiàn)嚴(yán)格的順序消息籽腕,簡(jiǎn)單且可行的辦法就是:保證? 生產(chǎn)者 - Server - 消費(fèi)者是一對(duì)一對(duì)一的關(guān)系

這樣的設(shè)計(jì)雖然簡(jiǎn)單易行嗡呼,但也會(huì)存在一些很嚴(yán)重的問題,比如:

1皇耗、并行度就會(huì)成為消息系統(tǒng)的瓶頸(吞吐量不夠)

2南窗、更多的異常處理,比如:只要消費(fèi)端出現(xiàn)問題廊宪,就會(huì)導(dǎo)致整個(gè)處理流程阻塞。


消息重復(fù)

消費(fèi)端1沒有響應(yīng)Server時(shí)有兩種情況:

1女轿、M1確實(shí)沒有到達(dá)(數(shù)據(jù)在網(wǎng)絡(luò)傳送中丟失)箭启;

2、消費(fèi)端已經(jīng)消費(fèi)M1且已經(jīng)發(fā)送響應(yīng)消息蛉迹,只是MQ Server端沒有收到傅寡。

如果是第二種情況,重發(fā)M1北救,就會(huì)造成M1被重復(fù)消費(fèi)荐操。也就引入了消息重復(fù)問題。

造成消息重復(fù)的根本原因是:網(wǎng)絡(luò)不可達(dá)珍策。

解決辦法:

1托启、消費(fèi)端處理消息的業(yè)務(wù)邏輯保持冪等性。

2攘宙、保證每條消息都有唯一編號(hào)且保證消息處理成功與去重表的日志同時(shí)出現(xiàn)屯耸。


版本號(hào)應(yīng)用

示例:一個(gè)產(chǎn)品的狀態(tài)有上線、下線蹭劈。消息M1是上線疗绣,M2是下線。不巧M1判重失敗铺韧,被投遞了兩次多矮,且第二次發(fā)生在M2之后,如果不做重復(fù)性判斷哈打,顯然最終狀態(tài)是錯(cuò)誤的塔逃。

引入版本號(hào):每個(gè)消息自帶一個(gè)版本號(hào)讯壶。

每次只接受比當(dāng)前版本號(hào)大的消息。初始版本為0患雏,當(dāng)消息1到達(dá)時(shí)鹏溯,將版本號(hào)更新為1。消息2到來(lái)時(shí)淹仑,因?yàn)榘姹咎?hào)>1.可以接收丙挽。? ? 同時(shí)更新版本號(hào)為2.當(dāng)另一條下線消息到來(lái)時(shí),如果版本號(hào)是3.則是真實(shí)的下線消息匀借。如果是1颜阐,則是重復(fù)投遞的消息。

新的問題:但很多時(shí)候吓肋,消息到來(lái)的順序錯(cuò)亂了凳怨。比如應(yīng)該的順序是12,到來(lái)的順序是21是鬼。

解決方案:只處理版本+1肤舞,如果想讓亂序的消息最后能夠正確的被組織,那么就應(yīng)該只接收比當(dāng)前版本號(hào)大一的消息均蜜。


參考及引用資料

1李剖、大型網(wǎng)站架構(gòu)之分布式消息隊(duì)列

2、RocketMQ原理簡(jiǎn)介

3囤耳、消息隊(duì)列設(shè)計(jì)精要

4篙顺、分布式開放消息系統(tǒng)(RocketMQ)的原理與實(shí)踐

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市充择,隨后出現(xiàn)的幾起案子德玫,更是在濱河造成了極大的恐慌,老刑警劉巖椎麦,帶你破解...
    沈念sama閱讀 216,744評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宰僧,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡观挎,警方通過查閱死者的電腦和手機(jī)撒桨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)键兜,“玉大人凤类,你說我怎么就攤上這事∑掌” “怎么了谜疤?”我有些...
    開封第一講書人閱讀 163,105評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我夷磕,道長(zhǎng)履肃,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,242評(píng)論 1 292
  • 正文 為了忘掉前任坐桩,我火速辦了婚禮尺棋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘绵跷。我一直安慰自己膘螟,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評(píng)論 6 389
  • 文/花漫 我一把揭開白布碾局。 她就那樣靜靜地躺著荆残,像睡著了一般。 火紅的嫁衣襯著肌膚如雪净当。 梳的紋絲不亂的頭發(fā)上内斯,一...
    開封第一講書人閱讀 51,215評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音像啼,去河邊找鬼俘闯。 笑死,一個(gè)胖子當(dāng)著我的面吹牛忽冻,可吹牛的內(nèi)容都是我干的真朗。 我是一名探鬼主播,決...
    沈念sama閱讀 40,096評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼甚颂,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蜜猾!你這毒婦竟也來(lái)了秀菱?” 一聲冷哼從身側(cè)響起振诬,我...
    開封第一講書人閱讀 38,939評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎衍菱,沒想到半個(gè)月后赶么,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,354評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡脊串,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評(píng)論 2 333
  • 正文 我和宋清朗相戀三年辫呻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片琼锋。...
    茶點(diǎn)故事閱讀 39,745評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡放闺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出缕坎,到底是詐尸還是另有隱情怖侦,我是刑警寧澤,帶...
    沈念sama閱讀 35,448評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站匾寝,受9級(jí)特大地震影響搬葬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜艳悔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評(píng)論 3 327
  • 文/蒙蒙 一急凰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧猜年,春花似錦抡锈、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至袁稽,卻和暖如春勿璃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背推汽。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工补疑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人歹撒。 一個(gè)月前我還...
    沈念sama閱讀 47,776評(píng)論 2 369
  • 正文 我出身青樓莲组,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親暖夭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子锹杈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評(píng)論 2 354

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)迈着,斷路器竭望,智...
    卡卡羅2017閱讀 134,652評(píng)論 18 139
  • 分布式開放消息系統(tǒng)(RocketMQ)的原理與實(shí)踐 來(lái)源:http://www.reibang.com/p/453...
    meng_philip123閱讀 12,920評(píng)論 6 104
  • 演講時(shí)如果很緊張,流經(jīng)血管的的腎上腺素極速身高裕菠,腎上腺素是給肌肉增壓的咬清,如果肌肉不在使用狀態(tài),腎上腺素的流動(dòng)會(huì)使肌...
    麥琪957閱讀 226評(píng)論 0 0
  • 這一年奴潘,大概是這輩子迄今最為焦慮的時(shí)候了吧旧烧,都是房子惹的禍。 其實(shí)買房子的想法画髓,大概有兩年的想法的吧掘剪,去年年初,從...
    時(shí)間的光閱讀 255評(píng)論 0 1
  • 思維導(dǎo)圖復(fù)盤如下圖奈虾,歡迎指正[畫的時(shí)候就想整個(gè)導(dǎo)圖的顏色需不需要控制顏色種類數(shù)夺谁?] 以下是練習(xí)
    AngieNi倪小丫閱讀 397評(píng)論 3 2