RocketMQ學(xué)習(xí)教程:03.消息投遞模式【云圖智聯(lián)】

消息中間件( Message Oriented Middleware,簡(jiǎn)稱MOM)在企業(yè)開發(fā)中變得越來(lái)越重要。本文介紹消息中間件中的四種消息投遞模型郊闯,主要是介紹模型的核心特性肌幽,以及不同模型之前的區(qū)別。這四種模型分別是:

PTP模型

Pub/Sub模型

Partition模型

Transfer模型(筆者自己起的名字)

?? ?? ? 其中PTP模型和Pub/Sub模型在JMS(Java Message Service)規(guī)范中有定義堆巧,消息中間件ActiveMQ就實(shí)現(xiàn)了JMS規(guī)范妄荔。JMS規(guī)范旨在于為消息中間件廠商提供了一個(gè)規(guī)范,使得Java應(yīng)用可以更加容易的訪問(wèn)不同的消息中間件產(chǎn)品谍肤,類似于我們可以通過(guò)JDBC規(guī)范定義的相關(guān)接口不同廠商的數(shù)據(jù)庫(kù)(Mysql/Oracle/SqlServer等)產(chǎn)品啦租。然而一些消息中間件,并沒有實(shí)現(xiàn)JMS規(guī)范荒揣,而是自己設(shè)計(jì)出了一套模型篷角,例如Kafka和RocketMQ就采用了Partition模型。此外業(yè)界還有一些其他的消息投遞模型系任,例如Transfer模型恳蹲,這是筆者自己起的名字虐块。

PTP模型

? ? ? ? Point-to-Point,點(diǎn)對(duì)點(diǎn)通信模型嘉蕾。PTP是基于隊(duì)列(Queue)的贺奠,一個(gè)隊(duì)列可以有多個(gè)生產(chǎn)者,和多個(gè)消費(fèi)者错忱。消息服務(wù)器按照收到消息的先后順序儡率,將消息放到隊(duì)列中。隊(duì)列中的每一條消息以清,只能由一個(gè)消費(fèi)者進(jìn)行消費(fèi)儿普,消費(fèi)之后就會(huì)從隊(duì)列中移除。

?

?? ?? ? 需要注意的是掷倔,盡管這里使用Queue的概念眉孩,但并不是先進(jìn)入隊(duì)列消息,一定會(huì)被先消費(fèi)勒葱。在存在多個(gè)下游Consumer情況下浪汪,一些消息中間件,例如ActiveMQ错森,為了提升消費(fèi)能力吟宦,會(huì)將隊(duì)列中的消息分發(fā)到不同Consumer并行進(jìn)行處理。這意味著消息發(fā)送的時(shí)候可能是有序的涩维,但是在消費(fèi)的時(shí)候殃姓,就變成無(wú)序了。

為了保證消費(fèi)的有序瓦阐,一些MQ提供了"專有消費(fèi)者”或者"排他消費(fèi)者”的概念蜗侈,在這種情況下,隊(duì)列中的消息僅允許一個(gè)消費(fèi)者進(jìn)行消費(fèi)睡蟋,如果存在多個(gè)消費(fèi)者踏幻,那么從中選擇一個(gè)。但是戳杀,這意味著在消息在處理中沒有了并行性该面。如果消息量很多的情況下,將會(huì)產(chǎn)生消息積壓信卡。

? ? ? ??為了解決"專有消費(fèi)者”的性能問(wèn)題隔缀,一些消息中間件采用分區(qū)的概念來(lái)解決性能問(wèn)題,我們將在后文進(jìn)行介紹傍菇。

Pub/Sub模型

?? ??? ?publish-and- subscribe猾瘸, 即發(fā)布訂閱模型。在Pub/Sub模型中,生產(chǎn)者將消息發(fā)布到一個(gè)主題(Topic)中牵触,訂閱了該Topic的所有下游消費(fèi)者淮悼,都可以接收到這條消息。如下圖:

?

?? ?? ? 通常情況下揽思,一個(gè)條消息只要被消費(fèi)一次就行了袜腥,那么什么情況下需要所有的消費(fèi)者都對(duì)這條消息進(jìn)行消費(fèi)呢?最典型的情況就是需要在內(nèi)存中對(duì)數(shù)據(jù)進(jìn)行緩存绰更,并需要實(shí)時(shí)進(jìn)行更新瞧挤。

例如,筆者做過(guò)一個(gè)違禁詞系統(tǒng)儡湾,對(duì)用戶輸入的評(píng)論內(nèi)容進(jìn)行違禁詞匯檢測(cè)。這個(gè)違禁詞系統(tǒng)执俩,部署了在N臺(tái)服務(wù)器上徐钠,為了提升檢測(cè)性能,每臺(tái)機(jī)器都會(huì)講違禁詞系統(tǒng)的詞庫(kù)全量加載內(nèi)存中役首,之后檢測(cè)時(shí)尝丐,對(duì)于用戶的評(píng)論內(nèi)容進(jìn)行分詞,判斷分詞后的內(nèi)容有沒有出現(xiàn)在違禁詞詞匯中衡奥。因?yàn)樵~庫(kù)中不可能包含所有的敏感詞爹袁,所以還要支持動(dòng)態(tài)的添加敏感詞。這個(gè)時(shí)候矮固,Pub/Sub模型就發(fā)揮作用了失息,每個(gè)機(jī)器上都啟動(dòng)一個(gè)consumer,當(dāng)生產(chǎn)者發(fā)送一個(gè)敏感詞到Topic中档址,所有的消費(fèi)者都會(huì)接受到這些消息盹兢,更新敏感詞庫(kù)。

Partition模型

為了解決在PTP模型下守伸,有序消息需要通過(guò)"專有消費(fèi)者”消費(fèi)帶來(lái)的性能問(wèn)題绎秒,一些消息中間件,如rocketmq尼摹,kafka采用了Partition模型见芹,即分區(qū)模型,如下所示:

?

?? ?? ? 生產(chǎn)者發(fā)送消息到某個(gè)Topic中時(shí)蠢涝,最終選擇其中一個(gè)Partition進(jìn)行發(fā)送玄呛。你可以將Parition模型中的分區(qū),理解為PTP模型的隊(duì)列惠赫,不同的是把鉴,PTP模型中的隊(duì)列存儲(chǔ)的是所有的消息,而每個(gè)Partition只會(huì)存儲(chǔ)部分?jǐn)?shù)據(jù)。

對(duì)于消息者庭砍,此時(shí)多了一個(gè)消費(fèi)者組的概念场晶,Paritition會(huì)在同一個(gè)消費(fèi)者組下的消費(fèi)者中進(jìn)行分配,每個(gè)消費(fèi)者只會(huì)消費(fèi)分配給自己的Paritition怠缸。例如上圖中诗轻,consumer 1分配到了parititon1,consumer 2分配到了parititon2和parititon3揭北,consumer N分配到了paritition 4扳炬。

?? ?? ? 通過(guò)這種方式,Paritition模式巧妙的將PTP模型和Pub/Sub模型結(jié)合在了一起搔体。

?? ??? ?對(duì)于PTP模型恨樟,一條消息只會(huì)由一個(gè)消費(fèi)者進(jìn)行消費(fèi),而Partition模型中每個(gè)分區(qū)最終也只會(huì)有一個(gè)消費(fèi)者進(jìn)行消費(fèi)疚俱。對(duì)于通過(guò)"專有消費(fèi)者"來(lái)保證全局消費(fèi)有序的場(chǎng)景劝术,在Partition模型中,只需保證創(chuàng)建的Topic只有一個(gè)Partition即可呆奕,這個(gè)Paritition最終也只會(huì)分配其中一個(gè)消費(fèi)者养晋。

?? ?? ? 另外,在絕大部分場(chǎng)景下梁钾,我們沒有必要保證全局有序绳泉,例如一個(gè)訂單產(chǎn)生了3條消息,分別是訂單創(chuàng)建姆泻,訂單付款零酪,訂單完成。消費(fèi)時(shí)麦射,要按照這個(gè)順序消費(fèi)才能有意義蛾娶。但是訂單之間是可以并行消費(fèi)的,例如將訂單1產(chǎn)生的3條消息發(fā)送到Partiton 1潜秋,將訂單2產(chǎn)生的3條消息發(fā)送到Partition 2蛔琅,如此便達(dá)到了不同訂單之間的并行消費(fèi)。

?? ?? ? 對(duì)于Pub/Sub模型峻呛,一條消息所有的下游消費(fèi)者都可以進(jìn)行消費(fèi)罗售。在Paritition模型中,只需要為每個(gè)消費(fèi)者設(shè)置成不同的消費(fèi)者組即可钩述。

?? ?? ? 然而寨躁,過(guò)多的消費(fèi)者組,會(huì)給消息中間件運(yùn)維帶來(lái)麻煩牙勘。所以一些消息中間件职恳,結(jié)合了Partition模型和Pub/Sub模型所禀。例例如RocketMQ,支持為消費(fèi)者組設(shè)置消費(fèi)模式放钦,如果是集群模式色徘,就按照上述描述進(jìn)行消費(fèi),如果是廣播模式操禀,就按照Pub/Sub模型進(jìn)行消費(fèi)褂策。

?? ?? ? 當(dāng)然,Partition模型也不全是優(yōu)點(diǎn)颓屑,其最大的限制在于Partition數(shù)量是固定的(雖然可以調(diào)整)斤寂,針對(duì)同一個(gè)消費(fèi)者組,一個(gè)Partition最多只可以分配給其中一個(gè)消費(fèi)者揪惦。當(dāng)消費(fèi)者的數(shù)量大于Partition數(shù)量時(shí)遍搞,這些多出來(lái)的消費(fèi)者將無(wú)法消費(fèi)到消息。一些消息中間件對(duì)此進(jìn)行了優(yōu)化器腋,即在對(duì)單個(gè)消費(fèi)者內(nèi)尾抑,同時(shí)啟動(dòng)多個(gè)線程,來(lái)消費(fèi)這個(gè)Partition中的數(shù)據(jù)蒂培,當(dāng)然前提是要求消息不是有序的,對(duì)于有序的消息榜苫,只能使用一個(gè)線程按順序消費(fèi)這個(gè)Partition中的數(shù)據(jù)护戳。

Transfer模型

?? ?? ? Paritition模型中的消費(fèi)者組概念很有用,同一個(gè)Topic下的消息可以由多個(gè)不同業(yè)務(wù)方進(jìn)行消費(fèi)垂睬,只要使用不同的消費(fèi)者組即可媳荒,不同消費(fèi)者組消費(fèi)到的位置單獨(dú)記錄,互不影響驹饺。?但是钳枕,Paritition模型還是限制了消費(fèi)者數(shù)量不能多于分區(qū)數(shù)。

?? ?? ? 因此赏壹,又有了另外一種消費(fèi)模型鱼炒,筆者稱之為Transfer模型,如下圖所示:

?

生產(chǎn)者還是將消息發(fā)送到Topic中蝌借,針對(duì)一個(gè)Topic昔瞧,可以創(chuàng)建多個(gè)通道,筆者稱之為channel菩佑。與分區(qū)不同的是自晰,發(fā)送到Topic中的每條消息,都會(huì)轉(zhuǎn)發(fā)到每個(gè)channel稍坯,因此每個(gè)channel都有這個(gè)Topic的全量數(shù)據(jù)酬荞。當(dāng)然,沒有必要把真的把消息體完整的拷貝一份到channel中,可以只記錄一下消息元數(shù)據(jù)混巧,表示有一條放到這個(gè)channel中了枪向。

?? ?? ? 消費(fèi)者在消費(fèi)消息時(shí),必須指定從哪個(gè)channel消費(fèi)牲剃。多個(gè)消費(fèi)者消費(fèi)同一個(gè)channel時(shí)遣疯,每條消息只會(huì)有一個(gè)消費(fèi)者消費(fèi)達(dá)到,這一點(diǎn)與PTP模型類似凿傅。事實(shí)上缠犀,我們可以認(rèn)為,消費(fèi)了同一個(gè)channel的消費(fèi)者聪舒,就自動(dòng)組成了一個(gè)消費(fèi)者組辨液。但是,與Partition模型不同的是箱残,這里沒有分區(qū)的概念滔迈,因此消費(fèi)者的數(shù)量可以是任意的。事實(shí)上被辑,GO語(yǔ)言編寫的NSQ消息中間件燎悍,采用的就是這種模型。

當(dāng)然盼理,這種模型與PTP一樣谈山,也不能保證被消息有序,除非通過(guò)類似于”專用消費(fèi)者”的概念宏怔。

免費(fèi)學(xué)習(xí)視頻歡迎關(guān)注云圖智聯(lián):https://e.yuntuzhilian.com/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末奏路,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子臊诊,更是在濱河造成了極大的恐慌鸽粉,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抓艳,死亡現(xiàn)場(chǎng)離奇詭異触机,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)壶硅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門威兜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人庐椒,你說(shuō)我怎么就攤上這事椒舵。” “怎么了约谈?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵笔宿,是天一觀的道長(zhǎng)犁钟。 經(jīng)常有香客問(wèn)我,道長(zhǎng)泼橘,這世上最難降的妖魔是什么涝动? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮炬灭,結(jié)果婚禮上醋粟,老公的妹妹穿的比我還像新娘。我一直安慰自己重归,他們只是感情好米愿,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鼻吮,像睡著了一般育苟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上椎木,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天违柏,我揣著相機(jī)與錄音,去河邊找鬼香椎。 笑死漱竖,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的畜伐。 我是一名探鬼主播闲孤,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼烤礁!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起肥照,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤脚仔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后舆绎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鲤脏,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年吕朵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了猎醇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡努溃,死狀恐怖硫嘶,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情梧税,我是刑警寧澤沦疾,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布称近,位于F島的核電站,受9級(jí)特大地震影響哮塞,放射性物質(zhì)發(fā)生泄漏刨秆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一忆畅、第九天 我趴在偏房一處隱蔽的房頂上張望衡未。 院中可真熱鬧,春花似錦家凯、人聲如沸缓醋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)改衩。三九已至,卻和暖如春驯镊,著一層夾襖步出監(jiān)牢的瞬間葫督,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工板惑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留橄镜,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓冯乘,卻偏偏與公主長(zhǎng)得像洽胶,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子裆馒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355