metaq

metaq與rocketmq區(qū)別
metaq屬于rocketmq阿里內(nèi)部定制化版本偎窘,整體基本一致

使用場景

1.削峰填谷:大促物流訂單創(chuàng)建
2.異步解耦:應(yīng)用解耦重要手段
3.異步數(shù)據(jù)同步:精衛(wèi)binlog同步
4.流計算:Flink等計算平臺

metaq是什么

是一個隊(duì)列模型的消息中間件凿傅,具有高性能泊交、高可靠、高實(shí)時宏浩、分布式特點(diǎn)知残。
Producer、Consumer比庄、隊(duì)列都可以分布式求妹。
Producer 向一些隊(duì)列輪流發(fā)送消息,隊(duì)列集合稱為 Topic印蔗,Consumer 如果做廣播消費(fèi)扒最,則一個consumer實(shí)例消費(fèi)這個 Topic 對應(yīng)的所有隊(duì)列丑勤,如果做集群消費(fèi)华嘹,則多個 Consumer 實(shí)例平均消費(fèi)這個 topic 對應(yīng)的隊(duì)列集合。
能夠保證嚴(yán)格的消息順序法竞。
提供豐富的消息拉取模式耙厚。
高效的訂閱者水平擴(kuò)展能力。
實(shí)時的消息訂閱機(jī)制岔霸。
億級消息堆積能力薛躬。

基本概念

消息:信息傳遞的載體,數(shù)據(jù)傳遞的基本單位
隊(duì)列:先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu)呆细,消息收發(fā)的負(fù)載均衡都是基于隊(duì)列的維度實(shí)現(xiàn)
Topic:消息主題型宝,一級消息類型,通過topic對消息進(jìn)行分類,每個topic下可以區(qū)分不同tag趴酣,同一個Topic下的數(shù)據(jù)梨树,會分片保存到不同的Broker上,而每一個分片單位岖寞,就叫做MessageQueue抡四。
消費(fèi)組:消費(fèi)分組的標(biāo)識,即sdk中的groupName仗谆,也是文檔中提交到的consumerID指巡,接收并消費(fèi)一類信息

物理結(jié)構(gòu)

NameServer:用于服務(wù)發(fā)現(xiàn),提供名稱服務(wù)隶垮,NameServer是一個幾乎無狀態(tài)節(jié)點(diǎn)藻雪,可集群部署,節(jié)點(diǎn)之間無任何信息同步(維護(hù)topic與broker關(guān)系岁疼,producer/consumer通過topic從nameserver獲取broker
Broker:MetaQ的服務(wù)器阔涉,負(fù)責(zé)消息中轉(zhuǎn),主要職責(zé)是存儲捷绒、轉(zhuǎn)發(fā)消息瑰排。 部署相對復(fù)雜,Broker 分為 Master 與 Slave暖侨,一個 Master 可以對應(yīng)多個 Slave椭住,但是一個 Slave 只能對應(yīng)一個 Master,Master 與 Slave 的對應(yīng)關(guān)系通過指定相同的 BrokerName字逗,不同的 BrokerId 來定義京郑。BrokerId為 0 表示 Master,非 0 表示 Slave葫掉。Master 也可以部署多個些举。每個 Broker 與 Name Server 集群中的所有節(jié)點(diǎn)建立長連接,定時注冊 Topic 信息到所有 NameServer俭厚。
Producer:消息生產(chǎn)者户魏,負(fù)責(zé)產(chǎn)生消息,一般是業(yè)務(wù)系統(tǒng)挪挤。 Producer 與 Name Server 集群中的其中一個節(jié)點(diǎn)(隨機(jī)選擇)建立長連接叼丑,定期從 Name Server 取 Topic 路由信息,并向提供 Topic 服務(wù)的 Master 建立長連接扛门,且定時向 Master 發(fā)送心跳鸠信。Producer 完全無狀態(tài),可集群部署论寨。
Consumer:消息消費(fèi)者星立,負(fù)責(zé)消費(fèi)消息爽茴,一般是后臺系統(tǒng)負(fù)責(zé)異步消費(fèi)。Consumer 與 Name Server 集群中的其中一個節(jié)點(diǎn)(隨機(jī)選擇)建立長連接绰垂,定期從 Name Server 取 Topic 路由信息闹啦,并向提供 Topic 服務(wù)的 Master、Slave 建立長連接辕坝,且定時向 Master窍奋、Slave 發(fā)送心跳。Consumer既可以從 Master 訂閱消息酱畅,也可以從 Slave 訂閱消息琳袄,訂閱規(guī)則由 Broker 配置決定。
Broker:MetaQ的服務(wù)器纺酸,負(fù)責(zé)消息中轉(zhuǎn)窖逗,主要職責(zé)是存儲、轉(zhuǎn)發(fā)消息餐蔬。 部署相對復(fù)雜碎紊,Broker 分為 Master 與 Slave,一個 Master 可以對應(yīng)多個 Slave樊诺,但是一個 Slave 只能對應(yīng)一個 Master仗考,Master 與 Slave 的對應(yīng)關(guān)系通過指定相同的 BrokerName,不同的 BrokerId 來定義词爬。BrokerId為 0 表示 Master秃嗜,非 0 表示 Slave。Master 也可以部署多個顿膨。每個 Broker 與 Name Server 集群中的所有節(jié)點(diǎn)建立長連接锅锨,定時注冊 Topic 信息到所有 NameServer。

Broker選舉
集群啟動時恋沃,三個節(jié)點(diǎn)都是follower必搞,發(fā)起投票后,三個節(jié)點(diǎn)都會給自己投票囊咏。這樣一輪投票下來恕洲,三個節(jié)點(diǎn)的term都是1,是一樣的匆笤,這樣是選舉不出Leader的研侣。
當(dāng)一輪投票選舉不出Leader后谱邪,三個節(jié)點(diǎn)會進(jìn)入隨機(jī)休眠炮捧,例如A休眠1秒,B休眠3秒惦银,C休眠2秒咆课。
一秒后末誓,A節(jié)點(diǎn)醒來,會把自己的term加一票书蚪,投為2喇澡。然后2秒時,C節(jié)點(diǎn)醒來殊校,發(fā)現(xiàn)A的term已經(jīng)是2晴玖,比自己的1大,就會承認(rèn)A是Leader为流,把自己的term也更新為2呕屎。實(shí)際上這個時候,A已經(jīng)獲得了集群中的多數(shù)票敬察,2票秀睛,A就會被選舉成Leader。這樣莲祸,一般經(jīng)過很短的幾輪選舉蹂安,就會選舉出一個Leader來。
到3秒時锐帜,B節(jié)點(diǎn)會醒來田盈,他也同樣會承認(rèn)A的term最大,他是Leader缴阎,自己的term也會更新為2缠黍。這樣集群中的所有Candidate就都確定成了leader和follower.
然后在一個任期內(nèi),A會不斷發(fā)心跳給另外兩個節(jié)點(diǎn)药蜻。當(dāng)A掛了后瓷式,另外的節(jié)點(diǎn)沒有收到A的心跳,就會都轉(zhuǎn)化成Candidate狀態(tài)语泽,重新發(fā)起選舉贸典。

存儲架構(gòu)

CommitLog:真正存儲消息,以物理文件存儲踱卵,每個Broker上的CommitLog被該機(jī)器所有的Queue共享廊驼。寫滿一個G之后寫下一個G,完全順序?qū)懲锷埃S機(jī)讀
ConsumerQueue:消費(fèi)者使用的邏輯隊(duì)列妒挎,每個Topic下的每個Queue都有一個對應(yīng)的ConsumeQueue文件,文件地址在$home/store/consumequeue/{topicName}/{queueId}
IndexFile:查詢用西饵,基于物理磁盤文件實(shí)現(xiàn) hash 索引酝掩;

過程:數(shù)據(jù)寫到commitlog后異步構(gòu)建consumerqueue文件和 IndexFile(索引文件)數(shù)據(jù);
consumerqueue 記錄當(dāng)前在commitlog的位移與長度眷柔,生成一個定長的20字節(jié)的consumerqueue單個文件(1.這個索引對應(yīng)的消息內(nèi)容存在commitlog的哪個offset期虾,2.記錄消息大小原朝,3.記錄消息tag hashcode)
IndexFile 只是為了消息查詢提供了一種通過 key 或時間區(qū)間來查詢消息的方法(也是根據(jù)存儲的commitlog offset去commitlog查找消息體),且這種通過 IndexFile 來查找消息的方法不影響發(fā)送與消費(fèi)消息的主流程镶苞,文件地址$home/store/index/{fileName}喳坠;

分區(qū)模型

topicA在broker1 和 broker2分別有topicA_1分區(qū), topicA_2分區(qū);topicA_3 分區(qū)茂蚓,topicA_4 分區(qū)壕鹉。每個分區(qū)里存是的commit log文件的索引信息。


消費(fèi)關(guān)系

消息發(fā)送
消息消費(fèi)

經(jīng)典的Producer聋涨、Broker御板、Consumer消費(fèi)模型,不同類型的消息以不同的Topic來區(qū)分牛郑。
為了解決性能問題怠肋,一個Topic可以根據(jù)需求設(shè)置一個或多個消息隊(duì)列,Message Quene類似數(shù)據(jù)庫中的分區(qū)淹朋。Producer按照負(fù)載均衡策略將消息發(fā)送至Topic里不同的消息隊(duì)列中笙各,Consumer可以從隊(duì)列中取出消息并發(fā)的去消費(fèi)。

讀寫模型

讀寫模型
  • 隨機(jī)讀础芍,盡可能讓讀命中 PAGECACHE杈抢,減少 IO 讀操作,所以內(nèi)存越大越好仑性。如果系統(tǒng)中堆積的消息過多惶楼,讀數(shù)據(jù)要訪問磁盤會不會由于隨機(jī)讀導(dǎo)致系統(tǒng)性能急劇下降,答案是否定的诊杆。
    訪問 PAGECACHE 時歼捐,即使只訪問 1k 的消息,系統(tǒng)也會提前預(yù)讀出更多數(shù)據(jù),在下次讀時曙聂,就可能命
    中內(nèi)存。
  • 隨機(jī)訪問 Commit Log 磁盤數(shù)據(jù),系統(tǒng) IO 調(diào)度算法設(shè)置為 NOOP 方式,會在一定程度上將完全的隨機(jī)
    讀變成順序跳躍方式,而順序跳躍方式讀較完全的隨機(jī)讀性能會高 5 倍以上寸士。
  • 由于 Consume Queue 存儲數(shù)據(jù)量極少婶博,而且是順序讀挠轴,在 PAGECACHE 預(yù)讀作用下委煤,Consume Queue 的讀性能幾乎與內(nèi)存一致,即使堆積情況下院峡。所以可認(rèn)為 Consume Queue 完全不會阻礙讀性能盹牧。
讀寫模型

DirectMemory模式只有在淘寶雙十一大促開啟,平時不開啟睛榄,這里犧牲了1ms左右的讀數(shù)據(jù)(DirectMemory異步寫入PageCache咧欣,但是直接從PageCache讀)

順序消息

順序消息

● 順序發(fā)布:對于指定的一個 Topic轨帜,客戶端將按照一定的先后順序進(jìn)行發(fā)送消息魄咕。
● 順序消費(fèi):對于指定的一個 Topic,按照一定的先后順序進(jìn)行接收消息蚌父,即先發(fā)送的消息一定會先被客戶端接收到哮兰。


全局順序

全局順序:對于指定的一個 Topic,所有消息按照嚴(yán)格的先入先出(FIFO)的順序進(jìn)行發(fā)布和消費(fèi)苟弛。


分區(qū)順序

分區(qū)順序:對于指定的一個 Topic喝滞,所有消息根據(jù) sharding key 進(jìn)行區(qū)塊分區(qū)。同一個分區(qū)內(nèi)的消息按照嚴(yán)格的 FIFO 順序進(jìn)行發(fā)布和消費(fèi)膏秫。Sharding key 是順序消息中用來區(qū)分不同分區(qū)的關(guān)鍵字段右遭,和普通消息的 Key 是完全不同的概念。(Sharding key如訂單,根據(jù)訂單進(jìn)行分區(qū))

事務(wù)消息

事務(wù)消息

發(fā)送事務(wù)消息基本流程
發(fā)送事務(wù)消息是一個二階段過程窘哈,類似于數(shù)據(jù)庫的二階段提交吹榴。其中,包括兩個過程:

  1. 發(fā)送Half消息滚婉。應(yīng)用發(fā)送Half消息到Broker图筹。消費(fèi)方此時不能拉取到消息,需要等待后續(xù)Half消息狀態(tài)满哪。(Half就是將該消息轉(zhuǎn)存到另一個topic中RMQ_SYS_TRANS_HALF_TOPIC)
  2. 發(fā)送事務(wù)狀態(tài)婿斥。應(yīng)用根據(jù)自身的事務(wù)執(zhí)行情況劝篷,對Half消息發(fā)送事務(wù)狀態(tài):Commit哨鸭、Rollback、UNKNOW(當(dāng)前無法判決事務(wù)狀態(tài)娇妓,如事務(wù)無法及時完成)像鸡。(事務(wù)檢查通過,將該消息存到目標(biāo)topic中)

● Commit哈恰。訂閱方就可以從Broker拉取消息消費(fèi)只估;
● Rollback。Broker會“刪除”(標(biāo)記刪除)此消息着绷,訂閱者無法消費(fèi)此消息蛔钙;
● UNKNOW。當(dāng)前Half消息不處理荠医,Broker會定期(時間間隔最長約30秒(有一定浮動吁脱,可能會根據(jù)情況調(diào)整))發(fā)送Check到發(fā)送方應(yīng)用上隨機(jī)一臺機(jī)器(配置相同producerGroup的任意機(jī)器),檢查對應(yīng)的事務(wù)狀態(tài)(默認(rèn)最多檢查10次彬向,直到Commit或者Rollback兼贡,超過就當(dāng)作Rollback處理)。如果執(zhí)行事務(wù)過程中拋出異常 或者 超出時間限制(默認(rèn)6s)娃胆,也會當(dāng)UNKNOW處理遍希。

注:如果對某Half消息發(fā)送Rollback后,后續(xù)對相同Half消息發(fā)送Commit里烦,只要Half消息仍然保存在磁盤上(數(shù)小時到數(shù)十小時)凿蒜,消費(fèi)方也可以拉取到消息消費(fèi)(例如:本地事務(wù)執(zhí)行時間(executeLocalTransactionBranch執(zhí)行時間)過長,此時Broker會主動check(調(diào)用checkLocalTransactionState)胁黑,此時checkLocalTransactionState由于數(shù)據(jù)庫缺失記錄返回Rollback篙程,但最后本地事務(wù)executeLocalTransactionBranch執(zhí)行成功,對同一個事務(wù)進(jìn)行Commit會成功)别厘。反過來則不成立虱饿,即只要Commit,消費(fèi)方就會消費(fèi)到消息,Rollback也不能改變狀態(tài)氮发。這是由于Rollback是標(biāo)記刪除的實(shí)現(xiàn)導(dǎo)致的渴肉。

發(fā)送事務(wù)狀態(tài)-executeLocalTransactionBranch-對應(yīng)上圖步驟2
(發(fā)送Half消息成功后,會立即調(diào)用這里判斷當(dāng)前的事務(wù)狀態(tài)爽冕。這里也可以寫業(yè)務(wù)操作事務(wù)的代碼--不建議)
主動check-需要監(jiān)聽事件-checkLocalTransactionState-對應(yīng)上圖步驟5

延遲消息與定時消息

延遲消息與定時消息

定時消息

類似事務(wù)消息仇祭,將消息hold住(修改topic和隊(duì)列信息放入到commitlog中)颈畸,將其放入延遲隊(duì)列中乌奇,定時輪訓(xùn)延遲隊(duì)列,到時間將消息拉出來正式放到commitlog中

死信隊(duì)列

當(dāng)一條消息消費(fèi)失敗眯娱,RocketMQ就會自動進(jìn)行消息重試礁苗。而如果消息超過最大重試次數(shù),RocketMQ就會認(rèn)為這個消息有問題徙缴。但是此時试伙,RocketMQ不會立刻將這個有問題的消息丟棄,而會將其發(fā)送到這個消費(fèi)者組對應(yīng)的一種特殊隊(duì)列:死信隊(duì)列。

通常,一條消息進(jìn)入了死信隊(duì)列浅萧,意味著消息在消費(fèi)處理的過程中出現(xiàn)了比較嚴(yán)重的錯誤,并且無法自行恢復(fù)蚤蔓。此時,一般需要人工去查看死信隊(duì)列中的消息糊余,對錯誤原因進(jìn)行排查秀又。然后對死信消息進(jìn)行處理,比如轉(zhuǎn)發(fā)到正常的Topic重新進(jìn)行消費(fèi)啄刹,或者丟棄涮坐。

實(shí)踐問題

RocketMQ 的消息機(jī)制
消息模型:使用標(biāo)準(zhǔn)的發(fā)布-訂閱模型,在 RocketMQ 中也有隊(duì)列(queue)這個概念誓军;
消費(fèi)機(jī)制

  • 通過“請求-確認(rèn)”機(jī)制保證消息傳遞可靠:在生產(chǎn)端袱讹,生產(chǎn)者先將消息發(fā)送給服務(wù)端,也就是 Broker昵时,服務(wù)端在收到消息并將消息寫入主題或者隊(duì)列中后捷雕,會給生產(chǎn)者發(fā)送確認(rèn)的響應(yīng),如果生產(chǎn)者沒有收到服務(wù)端的確認(rèn)或者收到失敗的響應(yīng)壹甥,則會重新發(fā)送消息救巷;在消費(fèi)端,消費(fèi)者在收到消息并完成自己的消費(fèi)業(yè)務(wù)邏輯后句柠,也會給服務(wù)端發(fā)送消費(fèi)成功的確認(rèn)浦译,服務(wù)端只有收到消費(fèi)確認(rèn)后棒假,才認(rèn)為一條消息被成功消費(fèi),否則它會給消費(fèi)者重新發(fā)送這條消息精盅,直到收到對應(yīng)的消費(fèi)成功確認(rèn)帽哑;
  • 利用“多隊(duì)列”提升消費(fèi)性能:每個主題包含多個隊(duì)列,通過多個隊(duì)列來實(shí)現(xiàn)多實(shí)例并行生產(chǎn)和消費(fèi)任意時刻叹俏,允許多個消費(fèi)者進(jìn)行消費(fèi)妻枕;
  • 每個主題包含多個隊(duì)列,通過多個隊(duì)列來實(shí)現(xiàn)多實(shí)例并行生產(chǎn)和消費(fèi)粘驰;
  • 生產(chǎn)者會往所有隊(duì)列發(fā)消息屡谐,但一條消息只會往其中的某個隊(duì)列發(fā)送一次;
  • 一個消費(fèi)組蝌数,在每個隊(duì)列上只能串行消費(fèi)愕掏,多個隊(duì)列加一起就是并行消費(fèi),并行度就是隊(duì)列數(shù)量籽前;
  • 一個消費(fèi)組在一個隊(duì)列上維護(hù)一個消費(fèi)位置(offset)亭珍,作為這個消費(fèi)組在這個隊(duì)列上消費(fèi)記錄敷钾;
  • 訂閱者是通過消費(fèi)組(Consumer Group)來體現(xiàn)的枝哄,每個消費(fèi)組都消費(fèi)主題中一份完整的消息,一條消息被 Consumer Group1 消費(fèi)過阻荒,也可被 Consumer Group2 消費(fèi)挠锥;
  • 消費(fèi)組中包含多個消費(fèi)者,同一個組內(nèi)的消費(fèi)者是競爭關(guān)系侨赡,每個消費(fèi)者負(fù)責(zé)消費(fèi)組內(nèi)的一部分消息蓖租,如果一條消息被消費(fèi)者 Consumer1 消費(fèi)了,那同組的其他消費(fèi)者就不會再收到這條消息羊壹;
  • RocketMQ 只在隊(duì)列上保證消息的有序性蓖宦,主題層面無法保證消息的嚴(yán)格順序;

消息如何發(fā)送到指定隊(duì)列
https://blog.csdn.net/lgxzzz/article/details/119617998

順序隊(duì)列怎么實(shí)現(xiàn)
1.rocketmq自帶
2.其他mq如果沒有順序隊(duì)列

1.拆分多個隊(duì)列油猫,每個隊(duì)列對應(yīng)一個消費(fèi)者
2.將要順序操作的消息存到一個內(nèi)存隊(duì)列中稠茂,然后統(tǒng)一發(fā)送消息,在消費(fèi)端順序處理情妖,保證事務(wù)
3.通過消息體加狀態(tài)機(jī)/order排序睬关,由業(yè)務(wù)判斷處理

rocketmq順序消息是怎么實(shí)現(xiàn)的
rocketMQ實(shí)現(xiàn)嚴(yán)格的順序消費(fèi)采用的方法是:保證同一個order的消息發(fā)送到同一個隊(duì)列
發(fā)送者發(fā)送消息時,會通過MessageQueue輪詢的方式保證消息盡量均勻的分布到所有的MessageQueue上毡证,而消費(fèi)者也就同樣需要從多個MessageQueue上消費(fèi)消息电爹。而MessageQueue是RocketMQ存儲消息的最小單元,他們之間的消息都是互相隔離的料睛,在這種情況下丐箩,是無法保證消息全局有序的摇邦。
而對于局部有序的要求,只需要將有序的一組消息都存入同一個MessageQueue里屎勘,這樣MessageQueue的FIFO設(shè)計天生就可以保證這一組消息的有序涎嚼。RocketMQ中,可以在發(fā)送者發(fā)送消息時指定一個MessageSelector對象挑秉,讓這個對象來決定消息發(fā)入哪一個MessageQueue法梯。這樣就可以保證一組有序的消息能夠發(fā)到同一個MessageQueue里。

MessageQueueSelector實(shí)現(xiàn)

SendResult sendResult = producer.send(msg, new MessageQueueSelector() {
                    @Override
                    public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
                        Long id = (Long) arg;
                        long index = id % mqs.size();
                        return mqs.get((int)index);
 }

有序消費(fèi)(MessageListenerOrderly)
隊(duì)列分配: 有序消費(fèi)要求消息按照順序被處理犀概,因此 RocketMQ 會將同一個隊(duì)列的消息分配給同一個消費(fèi)者線程立哑。這確保了同一個隊(duì)列內(nèi)的消息是有序的。
消息鎖定: 在有序消費(fèi)中姻灶,為了保證消息的順序性铛绰,通常會對隊(duì)列進(jìn)行鎖定,即同一時刻只有一個消費(fèi)者線程能夠處理該隊(duì)列的消息产喉。

并發(fā)消費(fèi)(MessageListenerConcurrently)
隊(duì)列分配: 并發(fā)消費(fèi)允許多個消息隊(duì)列被并行處理捂掰。RocketMQ 會將消息盡可能平均地分配給不同的消費(fèi)者線程,以提高并發(fā)性能曾沈。
無鎖定: 由于并發(fā)消費(fèi)不要求嚴(yán)格的順序性这嚣,不會對隊(duì)列進(jìn)行鎖定。多個消費(fèi)者線程可以并行處理不同隊(duì)列的消息塞俱,提高整體的消費(fèi)吞吐量姐帚。

消息是如何亂序的
生產(chǎn)者生產(chǎn)了 2 條消息 m1、m2障涯,如果要保證 m1 先于 m2 被消費(fèi)
m1罐旗、m2 發(fā)送到 MQ 的不同 server,m1 到達(dá)的比 m2 晚唯蝶;
m1九秀、m2 發(fā)送到 MQ 的同一 server,保證 m1 先于 m2 到達(dá) server粘我,根據(jù)先到達(dá)先消費(fèi)的原則鼓蜒,理論上,m1 會先于 m2 被消費(fèi)涂滴,但 m1 和 m2 被發(fā)送到不同的消費(fèi)者友酱,1)m1 到達(dá)消費(fèi)者的時間要比m2 晚,2)m1 和 m2 同時到達(dá)柔纵,但兩個消費(fèi)端的負(fù)載情況不一樣缔杉;

解決:簡單可行的辦法是保證生產(chǎn)者 - MQServer - 消費(fèi)者是一對一對一的關(guān)系,但為了保證消息集群的高容錯性和高吞吐量搁料,需要從業(yè)務(wù)層面來保證消息的順序而不僅僅依賴于消息系統(tǒng)或详,RocketMQ 通過輪詢所有隊(duì)列的方式來確定消息被發(fā)送到哪一個隊(duì)列(負(fù)載均衡策略)系羞,在獲取到路由信息以后,會根據(jù)MessageQueueSelector 實(shí)現(xiàn)的算法來選擇一個隊(duì)列霸琴,同一個 OrderId(訂單 id)獲取到的肯定是同一個隊(duì)列椒振;

補(bǔ)充:其 ta 保證順序消息 & 消息去重的方法
1.使用版本號:下游每次處理消息時,只接受比當(dāng)前版本大的消息梧乘,但也引入了問題澎迎,一是發(fā)送方必須要求消息帶上業(yè)務(wù)版本號,二是下游必須存儲消息的版本號且嚴(yán)格保證順序选调,整體實(shí)現(xiàn)需要較高的成本夹供;
2.使用狀態(tài)機(jī):業(yè)務(wù)方只需要自己維護(hù)一個狀態(tài)機(jī),定義各種狀態(tài)的流轉(zhuǎn)關(guān)系仁堪,例如哮洽,”下線”狀態(tài)只允許接收”上線”消息,“上線”狀態(tài)只能接收“下線消息”弦聂,如果上線收到上線消息鸟辅,或者下線收到下線消息,在消息不丟失和上游業(yè)務(wù)正確的前提下莺葫,要么是消息發(fā)重了匪凉,要么是順序到達(dá)反了,這時消費(fèi)者只需要把“我不能處理這個消息”告訴投遞者徙融,要求投遞者過一段時間重發(fā)即可洒缀,而且重發(fā)有一定要有次數(shù)限制瑰谜,以避免死循環(huán)欺冀;

rocketmq消費(fèi)模式
推/拉消息模式
一是消息中間件進(jìn)行數(shù)據(jù)消息推送,二是消費(fèi)者從消息中間件拉取數(shù)據(jù)消息萨脑;
push 方式:有消息就及時推給消費(fèi)者隐轩,延遲小,幾乎可以做到實(shí)時
pull 方式:消費(fèi)者可以根據(jù)自己能力拉取消息處理
rocketmq都支持

rocketmq消費(fèi)慢-批量消費(fèi)
當(dāng)rocketmq消費(fèi)較慢渤早,即使加機(jī)器改善也一般职车,此時可以使用批量消費(fèi),一次性消費(fèi)多條消息鹊杖;
通過消費(fèi)者開啟多線程消費(fèi)悴灵,然后統(tǒng)一CountDownLatch等待消費(fèi)后給ack;這里如果一次性消費(fèi)10條數(shù)據(jù)骂蓖,其中1條失敗了积瞒,整體返回失敗,然后重試登下,重試時一定要做好冪等茫孔,將成功的9條數(shù)據(jù)給冪等掉叮喳,正常處理失敗的;如果批量消費(fèi)大量失敗缰贝,且并發(fā)較高馍悟,可能會堆積消息,這里抉擇要注意剩晴。

消息如何保證消息不丟失
事務(wù)保證生產(chǎn)者確認(rèn)
消費(fèi)者同步ack

消費(fèi)冪等

發(fā)送時消息重復(fù)【消息 Message ID 不同】:MQ Producer 發(fā)送消息場景下锣咒,消息已成功發(fā)送到服務(wù)端并完成持久化,此時網(wǎng)絡(luò)閃斷或者客戶端宕機(jī)導(dǎo)致服務(wù)端應(yīng)答給客戶端失敗赞弥。如果此時 MQ Producer 意識到消息發(fā)送失敗并嘗試再次發(fā)送消息宠哄,MQ 消費(fèi)者后續(xù)會收到兩條內(nèi)容相同但是 Message ID 不同的消息。
投遞時消息重復(fù)【消息 Message ID 相同】嗤攻;MQ Consumer 消費(fèi)消息場景下毛嫉,消息已投遞到消費(fèi)者并完成業(yè)務(wù)處理,當(dāng)客戶端給服務(wù)端反饋應(yīng)答的時候網(wǎng)絡(luò)閃斷妇菱。為了保證消息至少被消費(fèi)一次承粤,MQ 服務(wù)端將在網(wǎng)絡(luò)恢復(fù)后再次嘗試投遞之前已被處理過的消息,MQ 消費(fèi)者后續(xù)會收到兩條內(nèi)容相同并且 Message ID 也相同的消息闯团。
基于上述第一種原因辛臊,內(nèi)容相同的消息 Message ID 可能會不同,真正安全的冪等處理房交,不建議以 Message ID 作為處理依據(jù)彻舰。最好的方式是以業(yè)務(wù)唯一標(biāo)識作為冪等處理的關(guān)鍵依據(jù),而業(yè)務(wù)的唯一標(biāo)識可以通過消息 Key 進(jìn)行設(shè)置

消息堆積(排除topic未配置等情況-真實(shí)消息堆積)

  1. 消費(fèi)正常候味,發(fā)送方量級增大超出消費(fèi)上限刃唤,出現(xiàn)堆積(此種較為少見)
  2. 消費(fèi)變慢,出現(xiàn)堆積(最為常見白群,通過鷹眼或者單機(jī)視角jstack尚胞、arthas、排查RT是否增長)
  3. 順序消費(fèi)帜慢,某個隊(duì)列某條數(shù)據(jù)消費(fèi)失敗笼裳,導(dǎo)致當(dāng)前隊(duì)列block,堆積增大(需要解決消費(fèi)失敗問題)

消費(fèi)變慢粱玲,簡單排查是由于消費(fèi)者耗時過高導(dǎo)致躬柬,還是消費(fèi)者處理異常導(dǎo)致;

解決方案

如果是耗時過高抽减,先增加機(jī)器允青,讓消息快速消費(fèi)掉,后續(xù)優(yōu)化性能
如果是處理異常胯甩,能快速解決就快速解決昧廷,不能快速解決要想辦法將數(shù)據(jù)消費(fèi)掉堪嫂,
可以通過簡單改造落庫數(shù)據(jù),然后慢慢解決木柬,后續(xù)重新消費(fèi)皆串;也可以改造成轉(zhuǎn)發(fā)到一個新的topic上,最終目標(biāo)是將積壓的消息消費(fèi)一部分眉枕;然后解決問題修復(fù)恶复;

為什么RocketMQ不使用Zookeeper作為注冊中心呢?
zp屬于cp速挑,也就是選擇了一致性谤牡,在選舉階段導(dǎo)致服務(wù)不可用,首先rocketmq是不會接受這一點(diǎn)的姥宝,rocketmq采用nameServer弱依賴注冊中心翅萤,即從nameServer獲取broker地址后緩存到生產(chǎn)者/消費(fèi)者本地保持長連接,這樣即使nameServer集群掛了腊满,也不會影響消息的生產(chǎn)與消費(fèi)套么;

Broker主從模式選擇
單Master模式
broker重啟服務(wù)不可用,不推薦
多Master模式
單臺機(jī)器宕機(jī)至拉起服務(wù)期間未消費(fèi)消息不可消費(fèi)碳蛋,實(shí)時性有影響胚泌;
多Master多Slave模式-異步復(fù)制
異步復(fù)制方式,主備有短暫消息延遲(毫秒級)肃弟,Master宕機(jī)可能丟失少量未同步到slave的消息
多Master多Slave模式-同步雙寫
HA采用同步雙寫方式玷室,即只有主備都寫成功,才向應(yīng)用返回成功笤受,性能比異步差10%左右

Master和Slave之間是怎么同步數(shù)據(jù)的呢穷缤?
消息在master和slave之間的同步是根據(jù)raft協(xié)議來進(jìn)行的:
1.在broker收到消息后,會被標(biāo)記為uncommitted狀態(tài)
2.然后會把消息發(fā)送給所有的slave
3.slave在收到消息之后返回ack響應(yīng)給master
4.master在收到超過半數(shù)的ack之后感论,把消息標(biāo)記為committed
5.發(fā)送committed消息給所有slave绅项,slave也修改狀態(tài)為committed

RocketMQ為什么速度快】
是因?yàn)槭褂昧隧樞虼鎯Αage Cache和異步刷盤比肄、零拷貝http://www.reibang.com/writer#/notebooks/38316468/notes/103545244/preview
我們在寫入commitlog的時候是順序?qū)懭氲哪叶福@樣比隨機(jī)寫入的性能就會提高很多
寫入commitlog的時候并不是直接寫入磁盤芳绩,而是先寫入操作系統(tǒng)的PageCache
最后由操作系統(tǒng)異步將緩存中的數(shù)據(jù)刷到磁盤

https://developer.aliyun.com/article/782409

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市撞反,隨后出現(xiàn)的幾起案子妥色,更是在濱河造成了極大的恐慌,老刑警劉巖遏片,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嘹害,死亡現(xiàn)場離奇詭異撮竿,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)笔呀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進(jìn)店門幢踏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人许师,你說我怎么就攤上這事房蝉。” “怎么了微渠?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵搭幻,是天一觀的道長。 經(jīng)常有香客問我逞盆,道長檀蹋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任云芦,我火速辦了婚禮续扔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘焕数。我一直安慰自己纱昧,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布堡赔。 她就那樣靜靜地躺著识脆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪善已。 梳的紋絲不亂的頭發(fā)上灼捂,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天,我揣著相機(jī)與錄音换团,去河邊找鬼悉稠。 笑死,一個胖子當(dāng)著我的面吹牛艘包,可吹牛的內(nèi)容都是我干的的猛。 我是一名探鬼主播,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼想虎,長吁一口氣:“原來是場噩夢啊……” “哼卦尊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起舌厨,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤岂却,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體躏哩,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡署浩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了扫尺。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片筋栋。...
    茶點(diǎn)故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖器联,靈堂內(nèi)的尸體忽然破棺而出二汛,到底是詐尸還是另有隱情,我是刑警寧澤拨拓,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布肴颊,位于F島的核電站,受9級特大地震影響渣磷,放射性物質(zhì)發(fā)生泄漏婿着。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一醋界、第九天 我趴在偏房一處隱蔽的房頂上張望竟宋。 院中可真熱鬧,春花似錦形纺、人聲如沸丘侠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蜗字。三九已至,卻和暖如春脂新,著一層夾襖步出監(jiān)牢的瞬間挪捕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工争便, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留级零,地道東北人。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓滞乙,卻偏偏與公主長得像奏纪,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子酷宵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評論 2 359

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