詳解RocketMQ的架構設計、關鍵特性、與應用場景

內容大綱:

  • RocketMQ的簡介與演進
  • RocketMQ的架構設計
  • RocketMQ的關鍵特性
  • RocketMQ的應用場景

RocketMQ的簡介

RocketMQ一個純java、分佈式、隊列模型的開源消息中間件,前身是MetaQ,是阿里研發的一個隊列模型的消息中間件,後開源給apache基金會成爲了apache的頂級開源項目,具有高性能、高可靠、高實時、分佈式特點。

file

RocketMQ的演進

RocketMQ一共前後經歷了三代演進:

1.第一代,推模式

數據存儲採用關係型數據庫,典型代表包括Notify、Napoli。

2.第二代,拉模式

自研的專有消息存儲,在日誌處理方面參考Kafka,典型代表MetaQ。

3.第三代,以拉模式爲主,兼有推模式

低延遲消息引擎RocketMQ,在二代功能特性的基礎上,爲電商金融領域添加了可靠重試、基於文件存儲的分佈式事務等特性。使用在了阿里大量的應用上,典型如雙11場景,具有萬億級消息流轉。

RocketMQ的架構設計

1.RocketMQ的核心組件

file

RocketMQ主要由NameServer、Broker、Producer以及Consumer四部分構成。

file

1)NameServer:主要負責對於源數據的管理,包括了對於Topic和路由信息的管理。

NameServer是一個功能齊全的服務器,其角色類似Dubbo中的Zookeeper,但NameServer與Zookeeper相比更輕量。主要是因爲每個NameServer節點互相之間是獨立的,沒有任何信息交互。

file

2) Producer

消息生產者,負責產生消息,一般由業務系統負責產生消息。

  • Producer由用戶進行分佈式部署,消息由Producer通過多種負載均衡模式發送到Broker集羣,發送低延時,支持快速失敗。

3 )Broker

消息中轉角色,負責存儲消息,轉發消息。

  • Broker是具體提供業務的服務器,單個Broker節點與所有的NameServer節點保持長連接及心跳,並會定時將Topic信息註冊到NameServer,順帶一提底層的通信和連接都是基於Netty實現的。
  • Broker負責消息存儲,以Topic爲緯度支持輕量級的隊列,單機可以支撐上萬隊列規模,支持消息推拉模型。
  • 官網上有數據顯示:具有上億級消息堆積能力,同時可嚴格保證消息的有序性。

4)Consumer

消息消費者,負責消費消息,一般是後臺系統負責異步消費。

  • Consumer也由用戶部署,支持PUSH和PULL兩種消費模式,支持集羣消費和廣播消息,提供實時的消息訂閱機制。

5)大致流程

Broker在啓動的時候會去向NameServer註冊並且定時發送心跳,Producer在啓動的時候會到NameServer上去拉取Topic所屬的Broker具體地址,然後向具體的Broker發送消息。具體如下圖:

file

2.RocketMQ的消息領域模型

主要分爲Message、Topic、Queue、Offset以及Group這幾部分。

file

1)Topic

Topic表示消息的第一級類型,比如一個電商系統的消息可以分爲:交易消息、物流消息等。一條消息必須有一個Topic。

最細粒度的訂閱單位,一個Group可以訂閱多個Topic的消息。

2)Tag

Tag表示消息的第二級類型,比如交易消息又可以分爲:交易創建消息,交易完成消息等。RocketMQ提供2級消息分類,方便靈活控制。

3)Group

組,一個組可以訂閱多個Topic。

4)Message Queue

消息的物理管理單位。一個Topic下可以有多個Queue,Queue的引入使得消息的存儲可以分佈式集羣化,具有了水平擴展能力。

在RocketMQ 中,所有消息隊列都是持久化,長度無限的數據結構,所謂長度無限是指隊列中的每個存儲單元都是定長,訪問其中的存儲單元使用Offset 來訪問,offset 爲 java long 類型,64 位,理論上在 100年內不會溢出,所以認爲是長度無限。

也可以認爲 Message Queue 是一個長度無限的數組,Offset 就是下標。

RocketMQ的關鍵特性

1.消息的順序

消息的順序指的是消息消費時,能按照發送的順序來消費。例如:一個訂單產生了 3 條消息,分別是訂單創建、訂單付款、訂單完成。消費時,要按照這個順序消費纔有意義。但同時訂單之間又是可以並行消費的。

RocketMQ是通過將“相同ID的消息發送到同一個隊列,而一個隊列的消息只由一個消費者處理“來實現順序消息。如下圖:

file

這樣對於同一個訂單的創建、付款和完成消息,確保按照這一順序被髮送和消費。

2.消息重複

1)消息重複的原因

消息領域有一個對消息投遞的QoS定義,分爲:

  • 最多一次(At most once)
  • 至少一次(At least once)
  • 僅一次( Exactly once)

file

幾乎所有的MQ產品都聲稱自己做到了Atleastonce。既然是至少一次,那避免不了消息重複,尤其是在分佈式網絡環境下。比如:網絡原因閃斷,ACK返回失敗等等故障,確認信息沒有傳送到消息隊列,導致消息隊列不知道自己已經消費過該消息了,再次將該消息分發給其他的消費者。

不同的消息隊列發送的確認信息形式不同,例如RabbitMQ是發送一個ACK確認消息,RocketMQ是返回一個CONSUME_SUCCESS成功標誌,kafka實際上有個offset的概念。

RocketMQ沒有內置消息去重的解決方案,最新版本是否支持還需確認。

2)消息去重

1)去重原則:使用業務端邏輯保持冪等性

冪等性:就是用戶對於同一操作發起的一次請求或者多次請求的結果是一致的,不會因爲多次點擊而產生了副作用,數據庫的結果都是唯一的,不可變的。

只要保持冪等性,不管來多少條重複消息,最後處理的結果都一樣,需要業務端來實現。

2)去重策略:保證每條消息都有唯一編號(比如唯一流水號),且保證消息處理成功與去重表的日誌同時出現。

建立一個消息表,拿到這個消息做數據庫的insert操作。給這個消息做一個唯一主鍵(primary key)或者唯一約束,那麼就算出現重複消費的情況,就會導致主鍵衝突,那麼就不再處理這條消息。

file

RocketMQ的應用場景

1.削峯填谷

比如如秒殺等大型活動時會帶來較高的流量脈衝,如果沒做相應的保護,將導致系統超負荷甚至崩潰。如果因限制太過導致請求大量失敗而影響用戶體驗,可以利用MQ 超高性能的消息處理能力來解決。

2.異步解耦

通過上、下游業務系統的鬆耦合設計,比如:交易系統的下游子系統(如積分等)出現不可用甚至宕機,都不會影響到核心交易系統的正常運轉。

3.順序消息

與FIFO原理類似,MQ提供的順序消息即保證消息的先進先出,可以應用於交易系統中的訂單創建、支付、退款等流程。

4.分佈式事務消息

比如阿里的交易系統、支付紅包等場景需要確保數據的最終一致性,需要引入 MQ 的分佈式事務,既實現了系統之間的解耦,又可以保證最終的數據一致性。

將大事務拆分成小事務,減少系統間的交互,既高效又可靠。再利用MQ 的可靠傳輸與多副本技術確保消息不丟,At-Least-Once 特性來最終確保數據的最終一致性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章