RocketMQ架構
概述
Apache RocketMQ是一個分散式訊息和流處理平臺,具有低延遲,高效能和高可靠性,億萬級容量和靈活的可擴充套件性。它由四部分組成:名稱伺服器,代理伺服器,生產者和消費者。它們中的每一個都可以水平擴充套件,而不會出現單點故障。如上圖所示。
名稱伺服器叢集
名稱伺服器提供輕量級服務發現和路由。每個名稱伺服器記錄完整的路由資訊,提供相應的讀寫服務,支援快速的儲存擴充套件。
代理叢集
代理關注的是訊息儲存,它通過提供輕量級主題(TOPIC)和佇列(QUEUE)機制來處理訊息儲存。他們支援推,拉模型,包含容錯機制(2個副本或3個副本), 能夠抵禦強峰值,並且按序積壓千億條訊息的的功能。此外,代理還提供容災,豐富的度量統計資料和報警機制,這些都是傳統訊息系統所缺少的。
生產者叢集
生產者支援分散式部署,分散式生產者通過多種負載平衡模式向代理叢集傳送訊息,傳送程式支援快速故障和低延遲。
消費者叢集
消費者叢集也支援推,拉模式的分散式部署。它還支援叢集消費和訊息廣播。它提供了實時訊息訂閱機制,可以滿足大多數消費者的需求,RocketMQ的網站為感興趣的使用者提供了一個非常簡單的快速入門指南。
名稱服務
名稱伺服器是一個功能齊全的服務,主要包含兩個功能:
- 代理管理:名稱伺服器從代理叢集接收註冊,並提供心跳機制來檢查代理是否存活。
- 路由管理:每個名稱伺服器將儲存有關代理叢集的整個路由資訊和用於客戶端查詢的佇列資訊。
如我們所知,RocketMQ客戶端(生產者/消費者)將從NameServer查詢佇列路由資訊,但是客戶端如何找到NameServer地址的呢?
有四種方式向客戶端提供名稱伺服器地址列表,如下:
- 程式設計方式: ext :
producer.setNamesrvAddr("ip:port")
. - Java 配置: ext:
rocket.namesrv.addr
. - 環境變數: ext:
NAMESRV_ADDR
. - HTTP端點.
關於更深入的介紹客戶端如何找到NameServer地址的,請檢視這裡
代理服務
代理伺服器負責訊息儲存和傳遞,訊息查詢,高可用保證等。
如下圖所示, 代理伺服器有以下幾個重要的子模組:
- 遠端處理模組:代理的入口,處理來自客戶端的請求。
- 客戶端管理模組:管理客戶端(生產者/消費者)並維護消費者的主題訂閱。
- 儲存服務模組:提供簡單的API來儲存或查詢物理磁碟中的訊息。
- 高可用服務模組:在主代理和從代理之間提供資料同步功能。
- 索引服務:根據特定key,建立訊息索引,並提供快速訊息查詢。
部署(Deployment)
本節介紹生產就緒,部署解決方案。一般來說,我們正在部署一個沒有單點故障的彈性RocketMQ叢集。
前提條件(Prerequisite)
在開始本節之前,請確保您已經閱讀了快速上手部分,並且熟悉RocketMQ的核心概念和元件。
生產就緒部署
- 名稱伺服器
為了確保叢集在一個例項當機時仍然能夠正常工作,建議使用兩個或多個名稱伺服器例項,只要有一個名稱伺服器例項處於存活狀態,整個叢集就保持服務狀態。
名稱伺服器遵循無共享設計模式,代理伺服器將心跳資料傳送到所有名稱伺服器,生產者和消費者可以在傳送/消費訊息時從任何可用的名稱伺服器查詢後設資料。
- 代理
代理可以根據其角色分為兩類:主代理和從代理。主代理提供RW(讀寫)訪問,而從代理只接收讀訪問。
要在沒有單點故障的情況下部署高可用RockeMQ叢集,應該部署一系列代理集。一個代理集包含一個主代理和幾個從代理,其中主代理brokerid設定為0,從代理brokerid設定為非0即可。一組代理集中都代理有相同的代理名稱(brokerName)。在極端情況下,在一個代理集中至少需要設定兩個代理。每個主題駐留在兩個或多個代理中。
配置
部署RocketMQ叢集時,建議使用以下配置:
Broker configuration
Property Name | Default value | Details |
---|---|---|
listenPort | 10911 | listen port for client |
namesrvAddr | null | name server address |
brokerIP1 | InetAddress for network interface | Should be configured if having multiple addresses |
brokerName | null | broker name |
brokerClusterName | DefaultCluster | this broker belongs to which cluster |
brokerId | 0 | broker id, 0 means master, positive integers mean slave |
storePathCommitLog | $HOME/store/commitlog/ | file path for commit log |
storePathConsumerQueue | $HOME/store/consumequeue/ | file path for consume queue |
mapedFileSizeCommitLog | 1024 * 1024 * 1024(1G) | mapped file size for commit log |
deleteWhen | 04 | When to delete the commitlog which is out of the reserve time |
fileReserverdTime | 72 | The number of hours to keep a commitlog before deleting it |
brokerRole | ASYNC_MASTER | SYNC_MASTER/ASYNC_MASTER/SLVAE |
flushDiskType | ASYNC_FLUSH | {SYNC_FLUSH/ASYNC_FLUSH}. Broker of SYNC_FLUSH mode flushes each message onto disk before acknowledging producer. Broker of ASYNC_FLUSH mode, on the other hand, takes advantage of group-committing, achieving better performance. |
CLI管理工具
RocketMQ提供了一個CLI(命令列介面)管理工具,用於查詢,管理和診斷各種問題。
如何獲得
管理工具是隨RocketMQ一起提供,你要麼下載一個預構建的二進位制版本,要麼自己從原始碼構建,這樣你就擁有它了。
如果您需要原始碼, RocketMQ工具模組包含其原始碼。
如何使用
管理工具非常容易使用,這裡處於演示的目的,假設為Linux的環境。在mq安裝目錄下的/bin目錄中,使用bash命令: mqadmin, 就可以看到以下的幫助選單:
The most commonly used mqadmin commands are:
updateTopic Update or create topic
deleteTopic Delete topic from broker and NameServer
updateSubGroup Update or create subscription group
deleteSubGroup Delete subscription group from broker
updateBrokerConfig Update broker's config
updateTopicPerm Update topic perm
topicRoute Examine topic route info
topicStatus Examine topic Status info
topicClusterList get cluster info for topic
brokerStatus Fetch broker runtime status data
queryMsgById Query Message by Id
queryMsgByKey Query Message by Key
queryMsgByUniqueKey Query Message by Unique key
queryMsgByOffset Query Message by offset
queryMsgByUniqueKey Query Message by Unique key
printMsg Print Message Detail
sendMsgStatus Send msg to broker
brokerConsumeStats Fetch broker consume stats data
producerConnection Query producer's socket connection and client version
consumerConnection Query consumer's socket connection, client version and subscription
consumerProgress Query consumers's progress, speed
consumerStatus Query consumer's internal data structure
cloneGroupOffset Clone offset from other group
clusterList List all of clusters
topicList Fetch all topic list from name server
updateKvConfig Create or update KV config
deleteKvConfig Delete KV config
wipeWritePerm Wipe write perm of broker in all name server
resetOffsetByTime Reset consumer offset by timestamp(without client restart)
updateOrderConf Create or update or delete order conf
cleanExpiredCQ Clean expired ConsumeQueue on broker.
cleanUnusedTopic Clean unused topic on broker
startMonitoring Start Monitoring
statsAll Topic and Consumer tps stats
syncDocs Synchronize wiki and issue to github.com
allocateMQ Allocate MQ
checkMsgSendRT Check message send response time
clusterRT List All clusters Message Send RT
複製程式碼
主從複製模式
為了確保不會丟失任何成功釋出的訊息,RocketMQ提供了一種複製模式,通過兩種複製方式: 同步和非同步,以獲得更強的永續性和高可用性。
主從複製: 同步/非同步代理
與許多複製系統一樣,同步代理要等到提交日誌被複制到從伺服器後才能確認。相反,非同步代理在主伺服器上處理訊息後立即返回。
如何配置
在conf資料夾下的rocketmq發行版附帶了三個預構建的配置供您參考。
2m-2s-sync
2m-2s-async
2m-noslave
複製程式碼
注意: 所有的配置使用非同步重新整理的方式.
部署
以2M-2S-SYNC的部署為例,首先,啟動兩個名稱伺服器,如快速啟動部分所示: 假設他們的IP為192.168.0.2和192.168.0.3
開啟代理(假設二進位制rocketmq位於/home/rocketmq/dist)
>cd /home/rocketmq/dist/bin
>bash mqbroker -c ../conf/2m-2s-sync/broker-a.properties -n 192.168.0.2:9876,192.168.0.3:9876
>bash mqbroker -c ../conf/2m-2s-sync/broker-a-s.properties -n 192.168.0.2:9876,192.168.0.3:9876
>bash mqbroker -c ../conf/2m-2s-sync/broker-b.properties -n 192.168.0.2:9876,192.168.0.3:9876
>bash mqbroker -c ../conf/2m-2s-sync/broker-b-s.properties -n 192.168.0.2:9876,192.168.0.3:9876
How to verify
Execute the following command to verify according to the CLI section:
> bash mqadmin clusterlist
複製程式碼
核心概念
瞭解了MQ的一些基本模型和概念之後,我們可以深入探討訊息傳遞系統設計的一些問題:
- 消費者併發問題
- 消費者熱點問題
- 消費者負載均衡問題
- 訊息路由
- 連線多路複用
- 灰度部署(Canary Deployments)
生產者
生產者將業務應用程式系統生成的訊息傳送給代理伺服器,RocketMQ提供了多種傳送模式: 同步,非同步和單向傳輸。
生產組
相同角色的生產者被分組在一起。如果一臺生產者例項在處理事務時當機了,代理可以聯絡同一生產者組的不同生產者例項來提交或者回滾事務。
考慮到所提供的生產者在傳送訊息時足夠強大,每個生產組只允許一例項,以避免不必要的生產者例項初始化。
消費者
消費者從代理伺服器中拉取消並將訊息輸入應用程式。從使用者應用的角度來看,提供了兩種型別的消費者:
推送消費者
另一方面,punsh-consumer封裝了訊息拉取,消耗進度和維護內部的其他工作,為終端使用者留下一個回撥介面來實現,該介面將在訊息到達時執行。
拉取消費者
拉消費者積極從代理伺服器中拉取訊息,一旦一批訊息被拉取出來,使用者應用程式就會啟動消費過程。
消費組
與前面提到的生產者組類似,具有完全相同角色的消費者被分組在一起,並命名為消費者組。
消費組是一個很好的概念,使得在訊息消費方面,實現負載均衡和容錯的目標非常容易。
注意:消費者組的消費例項必須具有完全相同的主題訂閱.
主題
主題是生產者投遞訊息,消費者拉取訊息的一個類別。主題的生產者,消費者的關係非常鬆散。具體來說,一個主題可以有0個,1個或者多個向其傳送訊息的生產者;相反,生產者可以傳送不同主題的訊息。從消費者角度來看,一個主題可以由0個,1個或多個消費者群體訂閱。同樣,只要消費組的例項保持訂閱一致,使用者組就可以訂閱一個或多個主題。
訊息
訊息是要傳遞的資訊。訊息必須有一個主題,可以將其解釋為要郵寄信件的地址。訊息還可以具有可選的標記和額外的鍵值對。例如,您可以為訊息設定業務ke,並在代理伺服器上查詢訊息,以診斷開發過程中的問題。
訊息佇列
主題被劃分為一個或多個子主題:"訊息佇列"。
標籤
換句話說,標籤子主題為使用者提供了額外的靈活性。對於標籤,來自同一業務模組的具有不同目的的訊息,可能具有相同的主題和不同標記。標籤將有助於保持程式碼的整潔和一致,而且標籤還可以幫助RocketMQ提供的查詢系統。
代理
代理是RocketMQ系統的主要組成部分,它接收來自生產者的訊息,儲存它們,並準備處理來自消費者的拉取請求。它還儲存與訊息相關的後設資料,包括消費組,消費進度偏移量和主題/佇列資訊。
名稱伺服器
名稱伺服器用作路由資訊提供者。生產者/消費者客戶端查詢主題以查詢相應的代理列表。
訊息模型
- 叢集
- 廣播
訊息順序
當使用DefaultMQPushConsumer時,您可以決定是有序的或者是併發的消費訊息。
- 有序的
按順序消費訊息意味著,訊息的消費順序與生產者為每個訊息佇列傳送的順序相同,如果您正在處理全域性順序是必需的場景,請確保您使用的主題只有一個訊息佇列。
注意:如果指定了按順序消費,則訊息消費的最大併發性是消費組訂閱的訊息佇列數。
- 併發的
當併發消費訊息時,消費的最大併發性僅僅受每個消費者客戶端指定的執行緒池的限制。
注意:在此模式下,不再保證訊息的順序