1. 程式人生 > 其它 >RocketMQ系列(一)——基礎篇

RocketMQ系列(一)——基礎篇

 

前言

本篇是RocketMQ系列的第一篇,主要針對對RocketMQ感興趣或想系統學習RocketMQ的同學,內容相對基礎,包括各種名稱與術語解釋、叢集架構以及所支援的各種特性與適用場景。想深入瞭解其原理的請閱讀後面的章節。

 RocketMQ系列(二)——應用篇
 RocketMQ系列(三)——原理篇

 RocketMQ是一款分散式訊息中介軟體,由阿里巴巴中介軟體團隊開發並用於生產環境,2016年捐贈給Apache開源基金會,隨後成為Apache的頂級專案。

 常見的訊息中介軟體還包括:RabbitMQ、Kafka、ActiveMQ,另外Redis也可以作為訊息中介軟體的一種簡單實現。

一、名詞解釋

Producer

   Producer :訊息的生產者,負責產生訊息,如:使用者完成支付後產生一條交易成功訊息。一個producer例項可以往多個topic傳送訊息。

 Producer Group:一類producer的集合,這類producer通常傳送同一種類型的訊息,且傳送邏輯一致。如:不同應用節點 or 不同渠道的交易訂單屬於同一類訊息。

 一般來說,在同一應用節點(JVM)的同一套配置中(通過unitName劃分,系列三原理篇會說明),一個Producer Group只能有一個producer例項。

 如果事務訊息出現異常,同一Group中的其它producer節點可以執行(服務端的)提交或回滾操作。

Consumer

   Consumer:訊息的消費者,負責消費訊息,如:活動服務接收到交易成功訊息後向使用者發放優惠券。一個consumer例項可以訂閱多個topic。

 Consumer Group:一類consumer的集合名稱,這類consumer消費同一類訊息,且消費邏輯一致。

 與Producer Group類似,在同一應用節點(JVM)的同一套配置中,一個Consumer Group只能有一個consumer例項。

 Push Consumer:consumer的一種,應用程式向consumer物件註冊一個Listener介面(MessageListener),一旦收到訊息,consumer會回撥Listener介面的方法。

 Pull Consumer:consumer的一種,應用程式主動從broker拉取訊息,主動權由應用程式控制。

Broker

   訊息中轉角色,一般也稱為Server,負責儲存和接受訊息拉取請求,producer傳送的訊息順序儲存在broker的queue中。

 broker的角色分為Master(主節點)和Slave(從節點),區別主要在於訊息只能往Master節點寫入,從節點被動從Master同步資料。

 一個broker可以儲存多個topic的queue,broker與topic是多對多的關係。

NameServer

   輕量級命名服務,producer、consumer和broker的路由控制中心,提供類似於服務註冊與發現功能,通常以叢集形式部署,彼此之間無通訊,區域性出問題不影響整個叢集,所以穩定性很高。

 每個NameServer維護著叢集中所有的broker及topic路由資訊。

Topic

 訊息主題,一級訊息型別,通過 topic 對訊息進行分類與業務隔離。如:交易成功訊息和使用者註冊訊息可以通過不同topic進行區分。

 topic是一個邏輯概念,一個topic可以劃分為多個queue,這些queue儲存在不同的broker中,broker與topic是多對多的關係。

 如果訊息量比較大的情況下,應該多指定幾個佇列以便分散broker和consumer的壓力。

Tag

 訊息標籤,二級訊息型別,用來進一步區分某個topic下的訊息分類,如用success、refund分別表示交易成功和退款的訂單訊息。

 消費者可以通過訂閱不同的tags來對topic下的訊息進行選擇性的消費。

Message

 訊息,傳送、儲存和消費的載體,一條訊息必須指定topic和訊息體(body),另外可以選擇性指定tags和keys。

Queue

 訊息佇列,由同一型別的訊息按傳送順序組成,broker中劃分儲存的最小單元,topic與queue的關係為一對多。

 同一類message順序組成queue,一個或多個queue組成topic,topic按queue維度存放在不同的broker中。

 實際上queue儲存的不是真正的訊息資料,而是指向commit log的訊息索引,commit log才是儲存訊息的結構。

Broker、Topic與Queue的關係

 建立topic時可以用叢集模式建立,每個broker中的queue數量相同;也可以用單個broker模式建立,這樣每個broker中的queue數量可能不同。它們之間的具體關係(單個broker模式建立topic)如下圖:

 

 

 ClientId (即ConsumerId)

代表消費者、傳送者啟動的客戶端id,MQClientInstance是根據clientId來生成單例的,也就是如果相同的clientId只會在第一次啟動生產者或者消費者時,生成MQClientInstance。

低版本時,一個jvm啟動多個消費者、或者啟動多個生產者,clientId是相同的,也就是共用MQClientInstance,就會有問題,後面部落格會討論。

這個clientId在叢集負載均衡模式下有作用,負載均衡是按照group、topic(消費佇列)來分配到各個消費者clientId(consumerId)的。

 

二、叢集架構

叢集部署結構

 

 

 啟動順序:1、NameServer啟動 → 2、Broker啟動 → 3、Broker建立topic → 4、Producer啟動 → 5、Consumer啟動

一般建議先啟動消費者,再啟動生產者;

通訊方式

縱軸表示通訊發起方,橫軸表示被連線方

  NameServer Broker Producer Consumer
NameServer 彼此無通訊 每隔10s掃描所有存活的broker,若2分鐘內沒有收到心跳包,則斷開與broker的連線,並更新topic與queue的關係 - -
Broker 每個broker與所有NameServer保持長連線,每隔30s向所有NameServer傳送包含了自身topic配置資訊的心跳包;包含資訊:地址,brokerName,brokerId,topic,queue等 彼此無通訊 每隔10s掃描所有存活的producer,若2分鐘內沒有收到心跳資料,則斷開與producer的連線 每隔10s掃描所有存活的consumer,若2分鐘內沒有收到心跳資料,則斷開與consumer的連線,並向該消費者組所有消費者發出通知,重新分配佇列進行消費
Producer 每個producer與一臺NameServer保持長連線,每隔30s查詢topic配置資訊;如果連線的NameServer宕機,則會自動連線下一個NameServer 每個producer和(topic的queue)關聯的所有broker保持長連線,每隔30s傳送心跳 彼此無通訊 彼此無通訊
Consumer 每個consumer與一臺NameServer保持長連線,每隔30s查詢topic配置資訊;如果連線的NameServer宕機,則會自動連線下一個NameServer 每個consumer和(topic的queue)關聯的所有broker保持長連線,每隔30s傳送心跳 彼此無通訊 彼此無通訊

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

叢集部署模式

   單Master:配置簡單,安全性低,一般不用於生產環境
 多Master:效能較高,但無法做到高可用,較少採用
 主從同步雙寫:主從節點都寫入成功後才向客戶端返回成功;一致性和安全性高但效能稍差;公司叢集採用該方式,2主2從共4個節點
 主從非同步複製:Master寫入成功立即返回,Slave非同步方式複製訊息;效能較高但有資料丟失風險

持久化方式

 同步刷盤:刷盤到檔案才會返回成功
 非同步刷盤:先返回,再重新整理到磁碟;公司叢集採用該方式

三、支援特性

訊息傳送方式

 同步傳送:傳送執行緒等待發送結果或超時;適用於絕大部分訊息較為重要的業務場景
 非同步傳送:呼叫傳送介面後不等待發送結果,繼續執行後續業務邏輯,提供傳送回撥介面(SendCallback);適用於訊息重要但又對傳送效率要求較高的場景
 單向傳送:只發送,不關心傳送結果;適用於併發量大,訊息重要性不高的場景

訊息獲取方式

push模式:(看起來是)broker將訊息推送給consumer,最常用模式
 優點:訊息處理及時,客戶端邏輯簡單
 缺點:訊息存放在消費者記憶體中,可能導致消費者的訊息積壓,處理緩慢
 適用場景:對於資料實時性要求高的場景

pull模式:consumer主動從broker拉取訊息
 優點:客戶端可以根據自己的消費能力進行消費,不會導致消費者訊息積壓
 缺點:應用程式邏輯稍複雜,需要記錄佇列的消費位置及拉取頻率等;拉取頻率高容易導致服務端壓力大,頻率低訊息得不得及時消費
 適用場景:生產者訊息數量大,消費邏輯複雜或消費能力較低的場景

訊息過濾

 TAG模式:常用的訊息過濾模式,傳送階段在構建訊息時指定TAG,consumer訂閱時可以訂閱多個TAG或模糊匹配
 SQL表示式:通過設定訊息的使用者屬性,過濾時執行SQL過濾表示式進行條件匹配。注意:預設不支援屬性過濾,要開啟該功能需要在broker的配置檔案中新增enablePropertyFilter = true並全部重啟後生效
 類過濾模式:自定義訊息過濾介面(MessageFilter)實現訊息過濾

 其中後兩種方式只支援push方式。

訊息模式

 叢集模式:通常同一個queue由consumer group中的固定consumer例項消費,但也有例外,如pull模式下拉取全部佇列進行消費;適用於大部分場景。
 廣播模式:每個consumer例項都會消費topic中的全部訊息;應用場景舉例:訂單服務中,節點本地記憶體儲存了使用者的新老使用者狀態,當新使用者變為老使用者時,需要通知所有節點更新本地狀態。

事務訊息

   支援先發送半訊息到broker,此時訊息無法被consumer消費,待producer本地事務完成後再通知broker該訊息可以被正常傳送。
 注意事務訊息與分散式事務的區別,前者指傳送訊息和本地事務的執行結果保持一致(本地事務執行完成則傳送成功,本地事務執行失敗則回滾傳送的訊息),後者指不同分散式節點之間的執行結果保持一致。
 應用場景舉例:下單成功才向用戶推送訂單訊息。

順序訊息

   指同一型別(topic)中具有先後順序的訊息,可以保證消費時的順序與傳送時保持一致。如:下單→付款→發貨。
 順序訊息分為全域性有序和區域性有序,全域性有序需要設定佇列數為1才能保證,這會大大降低系統吞吐量,一般應用實現區域性有序就能滿足要求。

 實現關鍵:有序傳送,有序儲存,有序消費,缺一不可
  有序傳送:由同一個producer單執行緒按產生順序傳送
  有序儲存:按照一定的規則選取同一個佇列傳送,如按照訂單號取模確定傳送的訊息佇列
  有序消費:一個消費者單執行緒消費,保證了FIFO

延遲訊息

 延遲訊息是指傳送出去的訊息不能馬上被消費,而是要等待某些固定的時間後才會投遞給真正的佇列進行消費。Apache版本支援18種特定時間延遲,阿里收費版支援精確到秒級的延遲。

 實現思想是broker為每種延遲時間的訊息建立一個佇列,該佇列對正常的消費者不可見,然後啟動執行緒輪詢這些佇列,如果有訊息達到延遲時間,就將其轉為普通訊息存放到真實的topic佇列下。

 應用場景舉例:使用者下單半小時後提醒其支付

 思考:如何實現支援任意時間的延遲?

訊息重試與死信佇列

 訊息因為各種原因消費失敗後,會被重新投遞到名為%RETRY%+${consumerGroup}的重試佇列(注意:該佇列以consumerGroup為維度而不是topic),並且每次投遞根據重試次數設定延遲級別。

 當重試次數達到一定限制後(預設16次)會成為死信訊息(DLM:Dead-Letter Message),死信訊息不會被立刻丟棄,而是存放在專門的佇列中,存放死信訊息的佇列就叫死信佇列(DLQ:Dead-Letter Queue)。

 進入死信佇列的訊息需要人工干預,通常有三種處理方式:
  1、直接丟棄
  2、將死信訊息重新投遞到正常的訊息佇列中
  3、建立專門處理死信佇列的consumer進行消費

思考:
  為什麼要設計重試佇列和死信佇列?
  延遲訊息與消費重試的關係?

 

轉載:https://blog.csdn.net/wp120453/article/details/111674222

 

 

 

 

TRANSLATE with x English
Arabic Hebrew Polish
Bulgarian Hindi Portuguese
Catalan Hmong Daw Romanian
Chinese Simplified Hungarian Russian
Chinese Traditional Indonesian Slovak
Czech Italian Slovenian
Danish Japanese Spanish
Dutch Klingon Swedish
English Korean Thai
Estonian Latvian Turkish
Finnish Lithuanian Ukrainian
French Malay Urdu
German Maltese Vietnamese
Greek Norwegian Welsh
Haitian Creole Persian  
  TRANSLATE with COPY THE URL BELOW Back EMBED THE SNIPPET BELOW IN YOUR SITE Enable collaborative features and customize widget: Bing Webmaster Portal Back     此頁面的語言為中文(簡體)   翻譯為        
  • 中文(簡體)
  • 中文(繁體)
  • 丹麥語
  • 烏克蘭語
  • 烏爾都語
  • 亞美尼亞語
  • 俄語
  • 保加利亞語
  • 克羅埃西亞語
  • 冰島語
  • 加泰羅尼亞語
  • 匈牙利語
  • 卡納達語
  • 印地語
  • 印尼語
  • 古吉拉特語
  • 哈薩克語
  • 土耳其語
  • 威爾士語
  • 孟加拉語
  • 尼泊爾語
  • 布林語(南非荷蘭語)
  • 希伯來語
  • 希臘語
  • 庫爾德語
  • 德語
  • 義大利語
  • 拉脫維亞語
  • 挪威語
  • 捷克語
  • 斯洛伐克語
  • 斯洛維尼亞語
  • 旁遮普語
  • 日語
  • 普什圖語
  • 毛利語
  • 法語
  • 波蘭語
  • 波斯語
  • 泰盧固語
  • 泰米爾語
  • 泰語
  • 海地克里奧爾語
  • 愛沙尼亞語
  • 瑞典語
  • 立陶宛語
  • 緬甸語
  • 羅馬尼亞語
  • 寮國語
  • 芬蘭語
  • 英語
  • 荷蘭語
  • 薩摩亞語
  • 葡萄牙語
  • 西班牙語
  • 越南語
  • 亞塞拜然語
  • 阿姆哈拉語
  • 阿爾巴尼亞語
  • 阿拉伯語
  • 韓語
  • 馬爾加什語
  • 馬拉地語
  • 馬拉雅拉姆語
  • 馬來語
  • 馬耳他語
  • 高棉語