前情提要
? 現(xiàn)如今,消息中間件已經(jīng)在很多公司的業(yè)務(wù)中被廣泛使用:業(yè)務(wù)解耦玖详,消峰填谷把介,對(duì)接大數(shù)據(jù),流式計(jì)算等等各種玩法層出不窮蟋座。伴隨著消息中間件的使用拗踢,你一定還聽(tīng)過(guò) "消息隊(duì)列",“pub-sub”這些名詞向臀,我們今天就來(lái)聊一下這些消息中間件提供給業(yè)務(wù)的可使用的 "Style"巢墅。
概述
? 不管如何使用消息中間件,其實(shí)都可以歸結(jié)到兩個(gè)步驟:消息的產(chǎn)生和消費(fèi)。消息中間件作為一種消息的暫存(當(dāng)前也可以持久存儲(chǔ))系統(tǒng)君纫,解耦消息的上下游驯遇,通過(guò)自身提供的高吞吐量,穩(wěn)定可靠性蓄髓,分布式可擴(kuò)展性等一系列特性保證消息被業(yè)務(wù)合理正確處理妹懒。
? 消息中間件依照消息數(shù)據(jù)如何從生產(chǎn)者移動(dòng)到消費(fèi)者可提供多種不同的“Style”,我們這里介始兩種最常見(jiàn)的Style: 消息隊(duì)列方式(Message queuing) 和 發(fā)布訂閱(publish-subscribe)方式双吆。
消息隊(duì)列方式
? 隊(duì)列方式,就是Message queuing会前。
? 我舉個(gè)例子好乐,我們?cè)趯懲瑫r(shí)處理大量任務(wù)的代碼時(shí),經(jīng)常會(huì)使用work線程池瓦宜,再搭配上一個(gè)任務(wù)隊(duì)列蔚万,有任務(wù)要處理時(shí)塞進(jìn)這個(gè)任務(wù)隊(duì)列,然后work線程池中的空閑線程就不斷地從這個(gè)任務(wù)隊(duì)列里取出任務(wù)作處理临庇。這里的每個(gè)work線程就可以看成是消息的消費(fèi)者反璃,一個(gè)任務(wù)只能被其中一個(gè)work線程處理,每個(gè)任務(wù)的處理過(guò)程有快有慢假夺,先被work線程取走的任務(wù)不一定先被完成淮蜈。
? 有張圖來(lái)形象地說(shuō)明一下:
到這里我們可以看到對(duì)于隊(duì)列方式,同一個(gè)topic的各個(gè)消息是被各消費(fèi)者分?jǐn)傁⒌囊丫恚瑸榱朔乐瓜⒈恢貜?fù)消費(fèi)梧田,通常在消費(fèi)者獲取到消息或處理完消息后對(duì)MQ中的消息作刪除或標(biāo)記。
如果消息隊(duì)列中的消費(fèi)堆積過(guò)多侧蘸,我們可以通過(guò)擴(kuò)容當(dāng)前的消費(fèi)者裁眯,來(lái)增加消息消費(fèi)的吞吐量。
通過(guò)對(duì)于無(wú)狀態(tài)的應(yīng)用更常使用這種方式讳癌,因此它們不要求按順序來(lái)消費(fèi)消息數(shù)據(jù)穿稳,它們更多地是希望能有更好的并發(fā)消費(fèi)能力和吞吐量。
很多消息系統(tǒng)將topic分成若干個(gè)partition, 為了增加消費(fèi)的吞吐量晌坤,會(huì)一味調(diào)大partition個(gè)數(shù)逢艘,這種方式需要綜合考量,成本方面不一定是最優(yōu)的
發(fā)布-訂閱方式
? 發(fā)布-訂閱方式泡仗,就是常說(shuō)的pub-sub方式埋虹。
? 發(fā)布者push消息到消息中間件里的某個(gè)topic上,各個(gè)訂閱者都會(huì)收到這個(gè)topic上的完整的消息娩怎,即每個(gè)訂閱者都能看到一樣的完整的topic視圖搔课,并且收到的消息的順序和消息被push到消息中間件時(shí)的順序是一致的。
? 我們舉個(gè)例子,比如訂閱報(bào)紙爬泥,每個(gè)訂閱者的信箱里每天都會(huì)收到相同的報(bào)紙柬讨,而且報(bào)紙肯定是按時(shí)間先后收到。
? 有張圖來(lái)形象地說(shuō)明一下:
發(fā)布-訂閱方式可以保證訂閱者接收到消息的順序袍啡,這在某些場(chǎng)景下非常有用踩官。比如它可以用來(lái)同步數(shù)據(jù)庫(kù)的binlog, 訂閱者通過(guò)這個(gè)binlog可以作數(shù)據(jù)庫(kù)同步。
境输。
常見(jiàn)消息中間件
Apache ActiveMQ, Amazon SQS, IBM Websphere MQ, RabbitMQ, 和 RocketMQ 基本上是 消息隊(duì)列方式蔗牡;
-
Apache Kafka這個(gè)比較有意思,它兩種style其實(shí)都支持嗅剖。如果你用來(lái)kafka, 那你一定知道在消費(fèi)時(shí)它有個(gè)consumer group的概念辩越。
- 同一個(gè) consumer group里可以包括多個(gè)consumer, 這些同屬一個(gè)group的consumer消費(fèi)數(shù)據(jù)屬于消息隊(duì)(message queuing)的方式;
- 如果將每一個(gè)consumer group看作是一個(gè)整體信粮,假設(shè)不存在內(nèi)部的consumer, 即把這個(gè)consumer group看作就是一個(gè)consumer 黔攒, 那不同的consumer group消費(fèi)數(shù)據(jù)就可看作是發(fā)布-訂閱(pub-sub)方式;
現(xiàn)在各種消息中間件很多很多强缘,又存在不同的style, 我們?cè)谶x擇的時(shí)候還是要根據(jù)自己業(yè)務(wù)的需求來(lái)評(píng)估選擇督惰。