基本概念
主題(topic)
表示一類消息的集合,每個主題包含若干條消息,每條消息只能屬于一個主題,是RocketMQ進行消息訂閱的基本單位
一個生產(chǎn)者可以同時發(fā)送多種Topic的消息,而一個消費者只能對某種特定的Topic感興趣,即只能訂閱和消費一種Topic的消息
標(biāo)簽(tag)
為消息設(shè)置的標(biāo)簽,用于同一主題下區(qū)分不同類型的消息,來自同一個業(yè)務(wù)單元的消息,可以根據(jù)不同的業(yè)務(wù)目的在同一主題下設(shè)置不同的標(biāo)簽,標(biāo)簽?zāi)軌蛴行У谋3执a的清晰度和連貫性,并優(yōu)化RocketMQ提供的查詢系統(tǒng)。消費者可以根據(jù)tag實現(xiàn)對不同子主題的不同消費邏輯,實現(xiàn)更好的擴展性。
隊列
存儲消息的物理實體,一個Topic中可以包含多個Queue,每個Queue中存放的就是Topic的消息,一個Topic的Queue也被稱為一個Topic中的消息分區(qū)。注意,一個Topic的Queue中的消息只能被一個消費者組中的一個消費者消費,一個Queue中的消息不允許同一個消費組中的多個消費者同時消費
消息的標(biāo)識(messageID/key)
RocketMQ中的每個消息擁有一個唯一的messageID,且可以攜帶具有業(yè)務(wù)員標(biāo)識的key,以方便對消息的查詢。需要注意的是messageID有兩個,在生產(chǎn)者send消息的時候會自動生成一個messageID,當(dāng)消息到達Broker后,Broker也會自動生成一個messageID
Producer
消息的生產(chǎn)者,負(fù)責(zé)生產(chǎn)消息。Producer通過MQ的負(fù)載均衡模塊選擇相應(yīng)的Broker集群隊列進行消息投遞,投遞過程支持快速失敗并且低延遲。RocketMQ中的消息生產(chǎn)者都是以生產(chǎn)者組的形式出現(xiàn)的,生產(chǎn)者組是同一類生產(chǎn)者的集合,這類Producer發(fā)送相同Topic類型的消息。一個生產(chǎn)者組可以同時發(fā)送多個主題的消息
Consumer
消息消費者,負(fù)責(zé)消費消息,一個消息消費者會從Broker服務(wù)器中獲取消息,并對消息進行相關(guān)業(yè)務(wù)處理。RocketMQ中的消息消費者可以消費者組的形式出現(xiàn),消息消費者組是一類消費者的集合,這類Consumer消費的是同一個Topic類型的消息。消費者組使得在消息消費方面,實現(xiàn)負(fù)載均衡(Queue的負(fù)載均衡)和容錯(一個Consumer掛了,該Consumer group下其他的consumer可以接著消費原consumer消費的queue)目標(biāo)變得非常容易。

注意:消費者組中的consumer的數(shù)量應(yīng)該小于等于訂閱Topic的Queue的數(shù)量,如果超出Queue的數(shù)量,則多出的consumer將不能消費消息
Name Server
NameServer是一個Broker與Topic路由的注冊中心,支持Broker的動態(tài)注冊與發(fā)現(xiàn)。
主要包含兩個功能
- Broker管理:接受Broker集群的注冊信息并且保存下來作為路由信息的基本數(shù)據(jù);提供心跳監(jiān)測機制,檢查Broker是否還存活
- 路由信息管理:每個NameServer 中都保存著Broker集群的整個路由信息和用于客戶端查詢的隊列信息。Producer和Consumer通過NameServer可以獲取整個Broker集群的路由信息,從而進行消息的投遞和消費。
路由注冊
NameServer 通常是以集群的方式部署,不過NameServer 是無狀態(tài)的,即NameServer 集群中的各個節(jié)點是無差異的,各個節(jié)點間相互不進行通信。各個節(jié)點之間是通過Broker節(jié)點啟動時,輪詢NameServer 列表,與每個NameServer 節(jié)點建立長連接,發(fā)起注冊請求,在NameServer 內(nèi)部維護著一個Broker列表,用來動態(tài)的存儲Broker的信息
Broker節(jié)點為了證明自己是活著的,為了維護與NameServer間的長連接,會將最新的信息以心跳包的方式上報給NameServer,每30s發(fā)送一次心跳,心跳包中包含BrokerId,Broker地址,Broker名稱,Broker所屬的集群名稱等。NameServer 在接收到心跳包后,會更新心跳的時間戳,記錄這個Broker的最新存活時間。
路由剔除
由于Broker關(guān)機,宕機或者網(wǎng)絡(luò)抖動等原因,NameServer 沒有收到Broker的心跳,NameServer 可能會將其從Broker中剔除。
NameServer 中有一個定時任務(wù),每隔10s就會掃描一次Broker表,查看每一個Broker的最新心跳時間戳,當(dāng)距離當(dāng)前時間超過120s,則會判定Broker失效。
路由發(fā)現(xiàn)
RocketMQ的路由發(fā)現(xiàn)采用的是Pull模型,當(dāng)Topic路由信息發(fā)生變化的時候,NameServer 不會主動推送給客戶端,而是客戶端定時拉取主題最新的路由。默認(rèn)客戶端每隔30s會拉取一次最新的路由信息。
- push模型:推送模型,是一個發(fā)布-訂閱模型,實時性較好,需要維護一個長連接,該模型適合實時性較高的場景,client數(shù)量不多。
- pull模型,拉取模型,存在實時性較差的問題
- long Polling模型:長輪詢模型
客戶端NameServer 選擇策略
客戶端在配置是必須寫上NameServer 集群的地址,name客戶端到底鏈接的是哪個NameServer 節(jié)點呢,客戶端首先會先選一個隨機數(shù),然后再與NameServer 節(jié)點數(shù)量取模,此時得到的就是所要鏈接的節(jié)點索引,然后就會進行鏈接,如果鏈接失敗,則會采用輪詢的策略,逐個嘗試其他的連接點。