RocketMq高階原理
1. 訊息模型
RocketMQ主要由 Producer、Broker、Consumer 三部分組成,其中Producer 負責生產訊息,Consumer 負責消費訊息,Broker 負責儲存訊息。Broker 在實際部署過程中對應一臺伺服器,每個Broker 可以儲存多個Topic的訊息,每個Topic的訊息也可以分片儲存於不同的 Broker。MessageQueue 用於儲存訊息的物理址,每個Topic中的訊息地址儲存於多個 Message Queue 中。ConsumerGroup 由多個Consumer 例項構成。
2. 訊息生產者(Producer)
負責生產訊息,一般由業務系統負責生產訊息。一個訊息生產者會把業務應用系統裡產生的訊息傳送到broker伺服器。RocketMQ提供多種傳送方式,同步傳送、非同步傳送、順序傳送、單向傳送。同步和非同步方式均需要Broker返回確認資訊,單向傳送不需要。
生產者中,會把同一類Producer組成一個集合,叫做生產者組,這類Producer傳送同一類訊息且傳送邏輯一致。如果傳送的是事務訊息且原始生產者在傳送之後崩潰,則Broker伺服器會聯絡同一生產者組的其他生產者例項以提交或回溯消費。
3.訊息消費者(Consumer)
負責消費訊息,一般是後臺系統負責非同步消費。一個訊息消費者會從Broker伺服器拉取訊息、並將其提供給應用程式。從使用者應用的角度而言提供了兩種消費形式:拉取式消費、推動式消費.
- 拉取式消費的應用通常主動呼叫Consumer的拉訊息方法從Broker伺服器拉訊息、主動權由應用控制。一旦獲取了批量訊息,應用就會啟動消費過程。
- 推動式消費模式下Broker收到資料後會主動推送給消費端,該消費模式一般實時性較高
消費者同樣會把同一類Consumer組成一個集合,叫做消費者組,這類Consumer通常消費同一類訊息且消費邏輯一致。消費者組使得在訊息消費方面,實現負載均衡和容錯的目標變得非常容易。要注意的是,消費者組的消費者例項必須訂閱完全相同的Topic。RocketMQ 支援兩種訊息模式:叢集消費(Clustering)和廣播消費(Broadcasting)。
- 叢集消費模式下,相同Consumer Group的每個Consumer例項平均分攤訊息。
- 廣播消費模式下,相同Consumer Group的每個Consumer例項都接收全量的訊息。
4. 主題(Topic)
表示一類訊息的集合,每個主題包含若干條訊息,每條訊息只能屬於一個主題,是RocketMQ進行訊息訂閱的基本單位。
同一個Topic下的資料,會分片儲存到不同的Broker上,而每一個分片單位,就叫做MessageQueue。MessageQueue是生產者傳送訊息與消費者消費訊息的最小單位。
5. 代理伺服器(Broker Server)
訊息中轉角色,負責儲存訊息、轉發訊息。代理伺服器在RocketMQ系統中負責接收從生產者傳送來的訊息並存儲、同時為消費者的拉取請求作準備。代理伺服器也儲存訊息相關的元資料,包括消費者組、消費進度偏移和主題和佇列訊息等。
Broker Server是RocketMQ真正的業務核心,包含了多個重要的子模組:
- Remoting Module:整個Broker的實體,負責處理來自clients端的請求。
- Client Manager:負責管理客戶端(Producer/Consumer)和維護Consumer的Topic訂閱資訊
- Store Service:提供方便簡單的API介面處理訊息儲存到物理硬碟和查詢功能。
- HA Service:高可用服務,提供Master Broker 和 Slave Broker之間的資料同步功能
- Index Service:根據特定的Message key對投遞到Broker的訊息進行索引服務,以提供訊息的快速查詢
而Broker Server要保證高可用需要搭建主從叢集架構。RocketMQ中有兩種Broker架構模式:
- 普通叢集:這種叢集模式下會給每個節點分配一個固定的角色,master負責響應客戶端的請求,並存儲訊息。slave則只負責對master的訊息進行同步儲存,並響應部分客戶端的讀請求。訊息同步方式分為同步同步和非同步同步。這種叢集模式下各個節點的角色無法進行切換,也就是說,master節點掛了,這一組Broker就不可用了。
- Dledger高可用叢集:Dledger是RocketMQ自4.5版本引入的實現高可用叢集的一項技術。這個模式下的叢集會隨機選出一個節點作為master,而當master節點掛了後,會從slave中自動選出一個節點升級成為master。
- 1、接管Broker的CommitLog訊息儲存
- 2、從叢集中選舉出master節點
- 3、完成master節點往slave節點的訊息同步。
- Dledger的關鍵部分是在他的節點選舉上。Dledger是使用Raft演算法來進行節點選舉的。
- 每個節點有三個狀態,Leader,follower和candidate(候選人)。正常執行的情況下,叢集中會有一個leader,其他都是follower,follower只響應Leader和Candidate的請求,而客戶端的請求全部由Leader處理,即使有客戶端請求到了一個follower,也會將請求轉發到leader。
- 叢集剛啟動時,每個節點都是follower狀態,之後叢集內部會發送一個timeout訊號,所有follower就轉成candidate去拉取選票,獲得大多數選票的節點選為leader,其他候選人轉為follower。如果一個timeout訊號發出時,沒有選出leader,將會重新開始一次新的選舉。而Leader節點會往其他節點發送心跳訊號,確認他的leader狀態。
6. 名字服務(Name Server)
名稱服務充當路由訊息的提供者。Broker Server會在啟動時向所有的Name Server註冊自己的服務資訊,並且後續通過心跳請求的方式保證這個服務資訊的實時性。生產者或消費者能夠通過名字服務查詢各主題相應的Broker IP列表。多個Namesrv例項組成叢集,但相互獨立,沒有資訊交換。這種特性也就意味著NameServer中任意的節點掛了,只要有一臺服務節點正常,整個路由服務就不會有影響。當然,這裡不考慮節點的負載情況。
7. 訊息
訊息系統所傳輸資訊的物理載體,生產和消費資料的最小單位,每條訊息必須屬於一個主題Topic。RocketMQ中每個訊息擁有唯一的Message ID,且可以攜帶具有業務標識的Key。系統提供了通過Message ID和Key查詢訊息的功能。
並且Message上有一個為訊息設定的標誌,Tag標籤。用於同一主題下區分不同型別的訊息。來自同一業務單元的訊息,可以根據不同業務目的在同一主題下設定不同標籤。標籤能夠有效地保持程式碼的清晰度和連貫性,並優化RocketMQ提供的查詢系統。消費者可以根據Tag實現對不同子主題的不同消費邏輯,實現更好的擴充套件性。