@[toc]
1. RocketMQ簡(jiǎn)單介紹
1.1 概念
1.1.1 消息模型(Message Model)
?RocketMQ主要由 Producer、Broker、Consumer 三部分組成,其中Producer 負(fù)責(zé)生產(chǎn)消息,Consumer 負(fù)責(zé)消費(fèi)消息,Broker 負(fù)責(zé)存儲(chǔ)消息。Broker 在實(shí)際部署過(guò)程中對(duì)應(yīng)一臺(tái)服務(wù)器叠聋,每個(gè) Broker 可以存儲(chǔ)多個(gè)Topic的消息,每個(gè)Topic的消息也可以分片存儲(chǔ)于不同的 Broker受裹。Message Queue 用于存儲(chǔ)消息的物理地址碌补,每個(gè)Topic中的消息地址存儲(chǔ)于多個(gè) Message Queue 中。ConsumerGroup 由多個(gè)Consumer 實(shí)例構(gòu)成。
1.1.2 消息生產(chǎn)者(Producer)
?負(fù)責(zé)生產(chǎn)消息厦章,一般由業(yè)務(wù)系統(tǒng)負(fù)責(zé)生產(chǎn)消息镇匀。一個(gè)消息生產(chǎn)者會(huì)把業(yè)務(wù)應(yīng)用系統(tǒng)里產(chǎn)生的消息發(fā)送到broker服務(wù)器。RocketMQ提供多種發(fā)送方式闷袒,同步發(fā)送坑律、異步發(fā)送、順序發(fā)送囊骤、單向發(fā)送晃择。同步和異步方式均需要Broker返回確認(rèn)信息,單向發(fā)送不需要也物。
1.1.3 消息生產(chǎn)者(Consumer)
?負(fù)責(zé)消費(fèi)消息宫屠,一般是后臺(tái)系統(tǒng)負(fù)責(zé)異步消費(fèi)。一個(gè)消息消費(fèi)者會(huì)從Broker服務(wù)器拉取消息滑蚯、并將其提供給應(yīng)用程序浪蹂。從用戶應(yīng)用的角度而言提供了兩種消費(fèi)形式:拉取式消費(fèi)、推動(dòng)式消費(fèi)告材。
1.1.4 主題(Topic)
?表示一類消息的集合坤次,每個(gè)主題包含若干條消息,每條消息只能屬于一個(gè)主題斥赋,是RocketMQ進(jìn)行消息訂閱的基本單位缰猴。
1.1.5 代理服務(wù)器(Broker Server)
?消息中轉(zhuǎn)角色,負(fù)責(zé)存儲(chǔ)消息疤剑、轉(zhuǎn)發(fā)消息滑绒。代理服務(wù)器在RocketMQ系統(tǒng)中負(fù)責(zé)接收從生產(chǎn)者發(fā)送來(lái)的消息并存儲(chǔ)、同時(shí)為消費(fèi)者的拉取請(qǐng)求作準(zhǔn)備隘膘。代理服務(wù)器也存儲(chǔ)消息相關(guān)的元數(shù)據(jù)疑故,包括消費(fèi)者組、消費(fèi)進(jìn)度偏移和主題和隊(duì)列消息等弯菊。
1.1.6 名字服務(wù)(Name Server)
?名稱服務(wù)充當(dāng)路由消息的提供者纵势。生產(chǎn)者或消費(fèi)者能夠通過(guò)名字服務(wù)查找各主題相應(yīng)的Broker IP列表。多個(gè)Namesrv實(shí)例組成集群管钳,但相互獨(dú)立吨悍,沒(méi)有信息交換。
1.1.7 拉取式消費(fèi)(Pull Consumer)
?Consumer消費(fèi)的一種類型蹋嵌,應(yīng)用通常主動(dòng)調(diào)用Consumer的拉消息方法從Broker服務(wù)器拉消息、主動(dòng)權(quán)由應(yīng)用控制葫隙。一旦獲取了批量消息栽烂,應(yīng)用就會(huì)啟動(dòng)消費(fèi)過(guò)程。
1.1.8 推動(dòng)式消費(fèi)(Push Consumer)
?Consumer消費(fèi)的一種類型,該模式下Broker收到數(shù)據(jù)后會(huì)主動(dòng)推送給消費(fèi)端腺办,該消費(fèi)模式一般實(shí)時(shí)性較高焰手。
1.1.9 集群消費(fèi)(Clustering)
?集群消費(fèi)模式下,相同Consumer Group的每個(gè)Consumer實(shí)例平均分?jǐn)傁ⅰ?/p>
1.1.10 廣播消費(fèi)(Broadcasting)
?廣播消費(fèi)模式下,相同Consumer Group的每個(gè)Consumer實(shí)例都接收全量的消息怀喉。
1.1.11 普通順序消息(Normal Ordered Message)
?普通順序消費(fèi)模式下书妻,消費(fèi)者通過(guò)同一個(gè)消費(fèi)隊(duì)列收到的消息是有順序的,不同消息隊(duì)列收到的消息則可能是無(wú)順序的躬拢。
1.1.12 嚴(yán)格順序消息(Strictly Ordered Message)
?嚴(yán)格順序消息模式下躲履,消費(fèi)者收到的所有消息均是有順序的。
1.1.13 消息(Message)
?消息系統(tǒng)所傳輸信息的物理載體聊闯,生產(chǎn)和消費(fèi)數(shù)據(jù)的最小單位工猜,每條消息必須屬于一個(gè)主題。RocketMQ中每個(gè)消息擁有唯一的Message ID菱蔬,且可以攜帶具有業(yè)務(wù)標(biāo)識(shí)的Key篷帅。系統(tǒng)提供了通過(guò)Message ID和Key查詢消息的功能。
1.1.14 標(biāo)簽(Tag)
?為消息設(shè)置的標(biāo)志拴泌,用于同一主題下區(qū)分不同類型的消息魏身。來(lái)自同一業(yè)務(wù)單元的消息,可以根據(jù)不同業(yè)務(wù)目的在同一主題下設(shè)置不同標(biāo)簽蚪腐。標(biāo)簽?zāi)軌蛴行У乇3执a的清晰度和連貫性箭昵,并優(yōu)化RocketMQ提供的查詢系統(tǒng)。消費(fèi)者可以根據(jù)Tag實(shí)現(xiàn)對(duì)不同子主題的不同消費(fèi)邏輯削茁,實(shí)現(xiàn)更好的擴(kuò)展性宙枷。
1.2 特性
1.2.1 訂閱與發(fā)布
消息的發(fā)布是指某個(gè)生產(chǎn)者向某個(gè)topic發(fā)送消息;消息的訂閱是指某個(gè)消費(fèi)者關(guān)注了某個(gè)topic中帶有某些tag的消息茧跋,進(jìn)而從該topic消費(fèi)數(shù)據(jù)慰丛。
1.2.2 消息順序
消息有序指的是一類消息消費(fèi)時(shí),能按照發(fā)送的順序來(lái)消費(fèi)瘾杭。例如:一個(gè)訂單產(chǎn)生了三條消息分別是訂單創(chuàng)建诅病、訂單付款、訂單完成粥烁。消費(fèi)時(shí)要按照這個(gè)順序消費(fèi)才能有意義贤笆,但是同時(shí)訂單之間是可以并行消費(fèi)的。RocketMQ可以嚴(yán)格的保證消息有序讨阻。
順序消息分為全局順序消息與分區(qū)順序消息芥永,全局順序是指某個(gè)Topic下的所有消息都要保證順序;部分順序消息只要保證每一組消息被順序消費(fèi)即可钝吮。
- 全局順序
對(duì)于指定的一個(gè) Topic埋涧,所有消息按照嚴(yán)格的先入先出(FIFO)的順序進(jìn)行發(fā)布和消費(fèi)板辽。
適用場(chǎng)景:性能要求不高,所有的消息嚴(yán)格按照 FIFO 原則進(jìn)行消息發(fā)布和消費(fèi)的場(chǎng)景 - 分區(qū)順序
對(duì)于指定的一個(gè) Topic棘催,所有消息根據(jù) sharding key 進(jìn)行區(qū)塊分區(qū)劲弦。 同一個(gè)分區(qū)內(nèi)的消息按照嚴(yán)格的 FIFO 順序進(jìn)行發(fā)布和消費(fèi)。 Sharding key 是順序消息中用來(lái)區(qū)分不同分區(qū)的關(guān)鍵字段醇坝,和普通消息的 Key 是完全不同的概念邑跪。
適用場(chǎng)景:性能要求高,以 sharding key 作為分區(qū)字段呼猪,在同一個(gè)區(qū)塊中嚴(yán)格的按照 FIFO 原則進(jìn)行消息發(fā)布和消費(fèi)的場(chǎng)景画畅。
1.2.3 消息過(guò)濾
RocketMQ的消費(fèi)者可以根據(jù)Tag進(jìn)行消息過(guò)濾,也支持自定義屬性過(guò)濾郑叠。消息過(guò)濾目前是在Broker端實(shí)現(xiàn)的夜赵,優(yōu)點(diǎn)是減少了對(duì)于Consumer無(wú)用消息的網(wǎng)絡(luò)傳輸,缺點(diǎn)是增加了Broker的負(fù)擔(dān)乡革、而且實(shí)現(xiàn)相對(duì)復(fù)雜寇僧。
1.2.4 消息可靠性
RocketMQ支持消息的高可靠,影響消息可靠性的幾種情況:
- Broker非正常關(guān)閉
- Broker異常Crash
- OS Crash
- 機(jī)器掉電沸版,但是能立即恢復(fù)供電情況
- 機(jī)器無(wú)法開(kāi)機(jī)(可能是cpu嘁傀、主板、內(nèi)存等關(guān)鍵設(shè)備損壞)
- 磁盤設(shè)備損壞
1)视粮、2)细办、3)、4) 四種情況都屬于硬件資源可立即恢復(fù)情況蕾殴,RocketMQ在這四種情況下能保證消息不丟笑撞,或者丟失少量數(shù)據(jù)(依賴刷盤方式是同步還是異步)。
5)钓觉、6)屬于單點(diǎn)故障茴肥,且無(wú)法恢復(fù),一旦發(fā)生荡灾,在此單點(diǎn)上的消息全部丟失瓤狐。RocketMQ在這兩種情況下,通過(guò)異步復(fù)制批幌,可保證99%的消息不丟础锐,但是仍然會(huì)有極少量的消息可能丟失。通過(guò)同步雙寫(xiě)技術(shù)可以完全避免單點(diǎn)荧缘,同步雙寫(xiě)勢(shì)必會(huì)影響性能皆警,適合對(duì)消息可靠性要求極高的場(chǎng)合,例如與Money相關(guān)的應(yīng)用截粗。注:RocketMQ從3.0版本開(kāi)始支持同步雙寫(xiě)耀怜。
1.2.5 至少一次
至少一次(At least Once)指每個(gè)消息必須投遞一次恢着。Consumer先Pull消息到本地,消費(fèi)完成后财破,才向服務(wù)器返回ack,如果沒(méi)有消費(fèi)一定不會(huì)ack消息从诲,所以RocketMQ可以很好的支持此特性左痢。
1.2.6 回溯消費(fèi)
回溯消費(fèi)是指Consumer已經(jīng)消費(fèi)成功的消息,由于業(yè)務(wù)上需求需要重新消費(fèi)系洛,要支持此功能俊性,Broker在向Consumer投遞成功消息后,消息仍然需要保留描扯。并且重新消費(fèi)一般是按照時(shí)間維度定页,例如由于Consumer系統(tǒng)故障,恢復(fù)后需要重新消費(fèi)1小時(shí)前的數(shù)據(jù)绽诚,那么Broker要提供一種機(jī)制典徊,可以按照時(shí)間維度來(lái)回退消費(fèi)進(jìn)度。RocketMQ支持按照時(shí)間回溯消費(fèi)恩够,時(shí)間維度精確到毫秒卒落。
1.2.7 事務(wù)消息
RocketMQ事務(wù)消息(Transactional Message)是指應(yīng)用本地事務(wù)和發(fā)送消息操作可以被定義到全局事務(wù)中,要么同時(shí)成功蜂桶,要么同時(shí)失敗儡毕。RocketMQ的事務(wù)消息提供類似 X/Open XA 的分布事務(wù)功能,通過(guò)事務(wù)消息能達(dá)到分布式事務(wù)的最終一致扑媚。
1.2.8 定時(shí)消息
定時(shí)消息(延遲隊(duì)列)是指消息發(fā)送到broker后腰湾,不會(huì)立即被消費(fèi),等待特定時(shí)間投遞給真正的topic疆股。
broker有配置項(xiàng)messageDelayLevel费坊,默認(rèn)值為“1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h”,18個(gè)level押桃】可以配置自定義messageDelayLevel。注意唱凯,messageDelayLevel是broker的屬性羡忘,不屬于某個(gè)topic。發(fā)消息時(shí)磕昼,設(shè)置delayLevel等級(jí)即可:msg.setDelayLevel(level)卷雕。level有以下三種情況:
- level == 0,消息為非延遲消息
- 1<=level<=maxLevel票从,消息延遲特定時(shí)間漫雕,例如level==1滨嘱,延遲1s
- level > maxLevel,則level== maxLevel浸间,例如level==20太雨,延遲2h
定時(shí)消息會(huì)暫存在名為SCHEDULE_TOPIC_XXXX的topic中,并根據(jù)delayTimeLevel存入特定的queue魁蒜,queueId = delayTimeLevel – 1囊扳,即一個(gè)queue只存相同延遲的消息,保證具有相同發(fā)送延遲的消息能夠順序消費(fèi)兜看。broker會(huì)調(diào)度地消費(fèi)SCHEDULE_TOPIC_XXXX锥咸,將消息寫(xiě)入真實(shí)的topic。
需要注意的是细移,定時(shí)消息會(huì)在第一次寫(xiě)入和調(diào)度寫(xiě)入真實(shí)topic時(shí)都會(huì)計(jì)數(shù)搏予,因此發(fā)送數(shù)量、tps都會(huì)變高弧轧。
1.2.9 消息重試
Consumer消費(fèi)消息失敗后雪侥,要提供一種重試機(jī)制,令消息再消費(fèi)一次劣针。Consumer消費(fèi)消息失敗通承8洌可以認(rèn)為有以下幾種情況:
- 由于消息本身的原因,例如反序列化失敗捺典,消息數(shù)據(jù)本身無(wú)法處理(例如話費(fèi)充值鸟廓,當(dāng)前消息的手機(jī)號(hào)被注銷,無(wú)法充值)等襟己。這種錯(cuò)誤通常需要跳過(guò)這條消息引谜,再消費(fèi)其它消息,而這條失敗的消息即使立刻重試消費(fèi)擎浴,99%也不成功员咽,所以最好提供一種定時(shí)重試機(jī)制,即過(guò)10秒后再重試贮预。
- 由于依賴的下游應(yīng)用服務(wù)不可用贝室,例如db連接不可用,外系統(tǒng)網(wǎng)絡(luò)不可達(dá)等仿吞。遇到這種錯(cuò)誤滑频,即使跳過(guò)當(dāng)前失敗的消息,消費(fèi)其他消息同樣也會(huì)報(bào)錯(cuò)唤冈。這種情況建議應(yīng)用sleep 30s峡迷,再消費(fèi)下一條消息,這樣可以減輕Broker重試消息的壓力。
RocketMQ會(huì)為每個(gè)消費(fèi)組都設(shè)置一個(gè)Topic名稱為“%RETRY%+consumerGroup”的重試隊(duì)列(這里需要注意的是绘搞,這個(gè)Topic的重試隊(duì)列是針對(duì)消費(fèi)組彤避,而不是針對(duì)每個(gè)Topic設(shè)置的),用于暫時(shí)保存因?yàn)楦鞣N異常而導(dǎo)致Consumer端無(wú)法消費(fèi)的消息夯辖×鹪ぃ考慮到異常恢復(fù)起來(lái)需要一些時(shí)間楼雹,會(huì)為重試隊(duì)列設(shè)置多個(gè)重試級(jí)別模孩,每個(gè)重試級(jí)別都有與之對(duì)應(yīng)的重新投遞延時(shí),重試次數(shù)越多投遞延時(shí)就越大贮缅。RocketMQ對(duì)于重試消息的處理是先保存至Topic名稱為“SCHEDULE_TOPIC_XXXX”的延遲隊(duì)列中,后臺(tái)定時(shí)任務(wù)按照對(duì)應(yīng)的時(shí)間進(jìn)行Delay后重新保存至“%RETRY%+consumerGroup”的重試隊(duì)列中介却。
1.2.10 消息重投
生產(chǎn)者在發(fā)送消息時(shí)谴供,同步消息失敗會(huì)重投,異步消息有重試齿坷,oneway沒(méi)有任何保證桂肌。消息重投保證消息盡可能發(fā)送成功、不丟失永淌,但可能會(huì)造成消息重復(fù)崎场,消息重復(fù)在RocketMQ中是無(wú)法避免的問(wèn)題。消息重復(fù)在一般情況下不會(huì)發(fā)生遂蛀,當(dāng)出現(xiàn)消息量大谭跨、網(wǎng)絡(luò)抖動(dòng),消息重復(fù)就會(huì)是大概率事件李滴。另外螃宙,生產(chǎn)者主動(dòng)重發(fā)、consumer負(fù)載變化也會(huì)導(dǎo)致重復(fù)消息所坯。如下方法可以設(shè)置消息重試策略:
- retryTimesWhenSendFailed:同步發(fā)送失敗重投次數(shù)谆扎,默認(rèn)為2,因此生產(chǎn)者會(huì)最多嘗試發(fā)送retryTimesWhenSendFailed + 1次芹助。不會(huì)選擇上次失敗的broker堂湖,嘗試向其他broker發(fā)送,最大程度保證消息不丟状土。超過(guò)重投次數(shù)无蜂,拋出異常,由客戶端保證消息不丟声诸。當(dāng)出現(xiàn)RemotingException酱讶、MQClientException和部分MQBrokerException時(shí)會(huì)重投。
- retryTimesWhenSendAsyncFailed:異步發(fā)送失敗重試次數(shù)彼乌,異步重試不會(huì)選擇其他broker泻肯,僅在同一個(gè)broker上做重試紊撕,不保證消息不丟。
- retryAnotherBrokerWhenNotStoreOK:消息刷盤(主或備)超時(shí)或slave不可用(返回狀態(tài)非SEND_OK)蛆挫,是否嘗試發(fā)送到其他broker淤袜,默認(rèn)false。十分重要消息可以開(kāi)啟稚铣。
1.2.11 流量控制
生產(chǎn)者流控箱叁,因?yàn)閎roker處理能力達(dá)到瓶頸;消費(fèi)者流控惕医,因?yàn)橄M(fèi)能力達(dá)到瓶頸耕漱。
生產(chǎn)者流控:
- commitLog文件被鎖時(shí)間超過(guò)osPageCacheBusyTimeOutMills時(shí),參數(shù)默認(rèn)為1000ms抬伺,返回流控螟够。
- 如果開(kāi)啟transientStorePoolEnable == true,且broker為異步刷盤的主機(jī)峡钓,且transientStorePool中資源不足妓笙,拒絕當(dāng)前send請(qǐng)求,返回流控能岩。
- broker每隔10ms檢查send請(qǐng)求隊(duì)列頭部請(qǐng)求的等待時(shí)間寞宫,如果超過(guò)waitTimeMillsInSendQueue,默認(rèn)200ms拉鹃,拒絕當(dāng)前send請(qǐng)求辈赋,返回流控。
- broker通過(guò)拒絕send 請(qǐng)求方式實(shí)現(xiàn)流量控制毛俏。
注意炭庙,生產(chǎn)者流控,不會(huì)嘗試消息重投煌寇。
消費(fèi)者流控:
- 消費(fèi)者本地緩存消息數(shù)超過(guò)pullThresholdForQueue時(shí)焕蹄,默認(rèn)1000。
- 消費(fèi)者本地緩存消息大小超過(guò)pullThresholdSizeForQueue時(shí)阀溶,默認(rèn)100MB腻脏。
- 消費(fèi)者本地緩存消息跨度超過(guò)consumeConcurrentlyMaxSpan時(shí),默認(rèn)2000银锻。
消費(fèi)者流控的結(jié)果是降低拉取頻率永品。
1.2.12 死信隊(duì)列
死信隊(duì)列用于處理無(wú)法被正常消費(fèi)的消息。當(dāng)一條消息初次消費(fèi)失敗击纬,消息隊(duì)列會(huì)自動(dòng)進(jìn)行消息重試鼎姐;達(dá)到最大重試次數(shù)后,若消費(fèi)依然失敗,則表明消費(fèi)者在正常情況下無(wú)法正確地消費(fèi)該消息炕桨,此時(shí)饭尝,消息隊(duì)列 不會(huì)立刻將消息丟棄,而是將其發(fā)送到該消費(fèi)者對(duì)應(yīng)的特殊隊(duì)列中献宫。
RocketMQ將這種正常情況下無(wú)法被消費(fèi)的消息稱為死信消息(Dead-Letter Message)钥平,將存儲(chǔ)死信消息的特殊隊(duì)列稱為死信隊(duì)列(Dead-Letter Queue)。在RocketMQ中姊途,可以通過(guò)使用console控制臺(tái)對(duì)死信隊(duì)列中的消息進(jìn)行重發(fā)來(lái)使得消費(fèi)者實(shí)例再次進(jìn)行消費(fèi)涉瘾。
1.3 架構(gòu)
1.3.1 技術(shù)架構(gòu)
RocketMQ架構(gòu)上主要分為四部分,如上圖所示:
Producer:消息發(fā)布的角色捷兰,支持分布式集群方式部署立叛。Producer通過(guò)MQ的負(fù)載均衡模塊選擇相應(yīng)的Broker集群隊(duì)列進(jìn)行消息投遞,投遞的過(guò)程支持快速失敗并且低延遲贡茅。
Consumer:消息消費(fèi)的角色囚巴,支持分布式集群方式部署。支持以push推友扰,pull拉兩種模式對(duì)消息進(jìn)行消費(fèi)。同時(shí)也支持集群方式和廣播方式的消費(fèi)庶柿,它提供實(shí)時(shí)消息訂閱機(jī)制村怪,可以滿足大多數(shù)用戶的需求。
NameServer:NameServer是一個(gè)非常簡(jiǎn)單的Topic路由注冊(cè)中心浮庐,其角色類似Dubbo中的zookeeper甚负,支持Broker的動(dòng)態(tài)注冊(cè)與發(fā)現(xiàn)。主要包括兩個(gè)功能:Broker管理审残,NameServer接受Broker集群的注冊(cè)信息并且保存下來(lái)作為路由信息的基本數(shù)據(jù)梭域。然后提供心跳檢測(cè)機(jī)制,檢查Broker是否還存活搅轿;路由信息管理病涨,每個(gè)NameServer將保存關(guān)于Broker集群的整個(gè)路由信息和用于客戶端查詢的隊(duì)列信息。然后Producer和Conumser通過(guò)NameServer就可以知道整個(gè)Broker集群的路由信息璧坟,從而進(jìn)行消息的投遞和消費(fèi)既穆。NameServer通常也是集群的方式部署,各實(shí)例間相互不進(jìn)行信息通訊雀鹃。Broker是向每一臺(tái)NameServer注冊(cè)自己的路由信息幻工,所以每一個(gè)NameServer實(shí)例上面都保存一份完整的路由信息。當(dāng)某個(gè)NameServer因某種原因下線了黎茎,Broker仍然可以向其它NameServer同步其路由信息囊颅,Producer,Consumer仍然可以動(dòng)態(tài)感知Broker的路由的信息。
-
BrokerServer:Broker主要負(fù)責(zé)消息的存儲(chǔ)、投遞和查詢以及服務(wù)高可用保證踢代,為了實(shí)現(xiàn)這些功能盲憎,Broker包含了以下幾個(gè)重要子模塊。
- Remoting Module:整個(gè)Broker的實(shí)體奸鬓,負(fù)責(zé)處理來(lái)自clients端的請(qǐng)求焙畔。
- Client Manager:負(fù)責(zé)管理客戶端(Producer/Consumer)和維護(hù)Consumer的Topic訂閱信息
- Store Service:提供方便簡(jiǎn)單的API接口處理消息存儲(chǔ)到物理硬盤和查詢功能。
- HA Service:高可用服務(wù)串远,提供Master Broker 和 Slave Broker之間的數(shù)據(jù)同步功能宏多。
- Index Service:根據(jù)特定的Message key對(duì)投遞到Broker的消息進(jìn)行索引服務(wù),以提供消息的快速查詢澡罚。
1.3.2 部署架構(gòu)
NameServer是一個(gè)幾乎無(wú)狀態(tài)節(jié)點(diǎn)伸但,可集群部署,節(jié)點(diǎn)之間無(wú)任何信息同步留搔。
Broker部署相對(duì)復(fù)雜更胖,Broker分為Master與Slave,一個(gè)Master可以對(duì)應(yīng)多個(gè)Slave隔显,但是一個(gè)Slave只能對(duì)應(yīng)一個(gè)Master却妨,Master與Slave 的對(duì)應(yīng)關(guān)系通過(guò)指定相同的BrokerName,不同的BrokerId 來(lái)定義括眠,BrokerId為0表示Master彪标,非0表示Slave。Master也可以部署多個(gè)掷豺。每個(gè)Broker與NameServer集群中的所有節(jié)點(diǎn)建立長(zhǎng)連接捞烟,定時(shí)注冊(cè)Topic信息到所有NameServer。 注意:當(dāng)前RocketMQ版本在部署架構(gòu)上支持一Master多Slave当船,但只有BrokerId=1的從服務(wù)器才會(huì)參與消息的讀負(fù)載题画。
Producer與NameServer集群中的其中一個(gè)節(jié)點(diǎn)(隨機(jī)選擇)建立長(zhǎng)連接,定期從NameServer獲取Topic路由信息德频,并向提供Topic 服務(wù)的Master建立長(zhǎng)連接苍息,且定時(shí)向Master發(fā)送心跳。Producer完全無(wú)狀態(tài)抱婉,可集群部署档叔。
Consumer與NameServer集群中的其中一個(gè)節(jié)點(diǎn)(隨機(jī)選擇)建立長(zhǎng)連接,定期從NameServer獲取Topic路由信息蒸绩,并向提供Topic服務(wù)的Master衙四、Slave建立長(zhǎng)連接,且定時(shí)向Master患亿、Slave發(fā)送心跳传蹈。Consumer既可以從Master訂閱消息押逼,也可以從Slave訂閱消息,消費(fèi)者在向Master拉取消息時(shí)惦界,Master服務(wù)器會(huì)根據(jù)拉取偏移量與最大偏移量的距離(判斷是否讀老消息挑格,產(chǎn)生讀I/O),以及從服務(wù)器是否可讀等因素建議下一次是從Master還是Slave拉取沾歪。
結(jié)合部署架構(gòu)圖漂彤,描述集群工作流程:
- 啟動(dòng)NameServer,NameServer起來(lái)后監(jiān)聽(tīng)端口灾搏,等待Broker挫望、Producer、Consumer連上來(lái)狂窑,相當(dāng)于一個(gè)路由控制中心媳板。
- Broker啟動(dòng),跟所有的NameServer保持長(zhǎng)連接泉哈,定時(shí)發(fā)送心跳包蛉幸。心跳包中包含當(dāng)前Broker信息(IP+端口等)以及存儲(chǔ)所有Topic信息。注冊(cè)成功后丛晦,NameServer集群中就有Topic跟Broker的映射關(guān)系奕纫。
- 收發(fā)消息前,先創(chuàng)建Topic烫沙,創(chuàng)建Topic時(shí)需要指定該Topic要存儲(chǔ)在哪些Broker上若锁,也可以在發(fā)送消息時(shí)自動(dòng)創(chuàng)建Topic。
- Producer發(fā)送消息斧吐,啟動(dòng)時(shí)先跟NameServer集群中的其中一臺(tái)建立長(zhǎng)連接,并從NameServer中獲取當(dāng)前發(fā)送的Topic存在哪些Broker上仲器,輪詢從隊(duì)列列表中選擇一個(gè)隊(duì)列煤率,然后與隊(duì)列所在的Broker建立長(zhǎng)連接從而向Broker發(fā)消息。
- Consumer跟Producer類似乏冀,跟其中一臺(tái)NameServer建立長(zhǎng)連接蝶糯,獲取當(dāng)前訂閱Topic存在哪些Broker上,然后直接跟Broker建立連接通道辆沦,開(kāi)始消費(fèi)消息昼捍。
2. RocketMQ和別的消息中間件的對(duì)比
2.1 RabbitMQ,Kafka肢扯,RocketMQ
?這里直接參考網(wǎng)上的一篇文章妒茬,其實(shí)關(guān)于這種比較的文章比較多,可以直接在網(wǎng)上進(jìn)行搜索蔚晨。
RabbitMQ乍钻,Kafka肛循,RocketMQ比較