RocketMQ部署開發
前言
RocketMQ是阿里巴巴團隊研發的高效能、分散式訊息中介軟體,已捐贈給Apache基金會,面向所有開發人員開源免費使用,本文主要參考其官方快速文件(http://jm.taobao.org/2017/01/12/rocketmq-quick-start-in-10-minutes/)和自己親自動手實踐,我們從瞭解RocketMQ開始,循序漸進,一步一步親自實現中介軟體部署,測試訊息收發,從理論和實踐兩方面學會使用RocketMQ。
1.RocketMQ 是什麼?
上圖是一個典型的訊息中介軟體收發訊息的模型,RocketMQ也是這樣的設計,簡單說來,RocketMQ具有以下特點:
o 是一個佇列模型的訊息中介軟體,具有高效能、高可靠、高實時、分散式特點。
o Producer、Consumer、佇列都可以分散式。
o Producer向一些佇列輪流傳送訊息,佇列集合稱為Topic,Consumer如果做廣播消費,則一個consumer例項消費這個Topic對應的所有佇列,如果做叢集消費,則多個Consumer例項平均消費這個topic對應的佇列集合。
o 能夠保證嚴格的訊息順序
o 提供豐富的訊息拉取模式
o 高效的訂閱者水平擴充套件能力
o 實時的訊息訂閱機制
o 億級訊息堆積能力
o 較少的依賴
2.RocketMQ 物理部署結構
如上圖所示, RocketMQ的部署結構有以下特點:
o Name Server是一個幾乎無狀態節點,可叢集部署,節點之間無任何資訊同步。
o Broker部署相對複雜,Broker分為Master與Slave,一個Master可以對應多個Slave,但是一個Slave只能對應一個Master,Master與Slave的對應關係通過指定相同的BrokerName,不同的BrokerId來定義,BrokerId為0表示Master,非0表示Slave。Master也可以部署多個。每個Broker與Name Server叢集中的所有節點建立長連線,定時註冊Topic資訊到所有Name Server。
o Producer與Name Server叢集中的其中一個節點(隨機選擇)建立長連線,定期從Name Server取Topic路由資訊,並向提供Topic服務的Master建立長連線,且定時向Master傳送心跳。Producer完全無狀態,可叢集部署。
o Consumer與Name Server叢集中的其中一個節點(隨機選擇)建立長連線,定期從Name Server取Topic路由資訊,並向提供Topic服務的Master、Slave建立長連線,且定時向Master、Slave傳送心跳。Consumer既可以從Master訂閱訊息,也可以從Slave訂閱訊息,訂閱規則由Broker配置決定。
3.RocketMQ 邏輯部署結構
如上圖所示,RocketMQ的邏輯部署結構有Producer和Consumer兩個特點。
Producer Group
用來表示一個傳送訊息應用,一個Producer Group下包含多個Producer例項,可以是多臺機器,也可以是一臺機器的多個程序,或者一個程序的多個Producer物件。一個Producer Group可以傳送多個Topic訊息,Producer Group作用如下:
1. 標識一類Producer
2. 可以通過運維工具查詢這個傳送訊息應用下有多個Producer例項
3. 傳送分散式事務訊息時,如果Producer中途意外宕機,Broker會主動回撥Producer Group內的任意一臺機器來確認事務狀態。
Consumer Group
用來表示一個消費訊息應用,一個Consumer Group下包含多個Consumer例項,可以是多臺機器,也可以是多個程序,或者是一個程序的多個Consumer物件。一個Consumer Group下的多個Consumer以均攤方式消費訊息,如果設定為廣播方式,那麼這個Consumer Group下的每個例項都消費全量資料。
4.RocketMQ 資料儲存結構
如上圖所示,RocketMQ採取了一種資料與索引分離的儲存方法。有效降低檔案資源、IO資源,記憶體資源的損耗。即便是阿里這種海量資料,高併發場景也能夠有效降低端到端延遲,並具備較強的橫向擴充套件能力。
5.RocketMQ安裝前準備
安裝環境
² 64位作業系統,最好有Linux / Unix / Mac;
² 64bit JDK 1.8+;
² Maven 3.x
² Git
注:官方文件上是從GitHub上跟新程式碼到本地編譯的方式安裝的,如果是直接下載安裝包的方式安裝,則不需要Maven和Git,本次安裝採用下載安裝包的方式安裝,作業系統是CentOS7,JDK8,另外在JDK9上RocketMQ會出現啟動nameserver異常,日誌如下,vm建立失敗,網上還沒找到解決辦法,等後續版本加強對JDK9的支援再用會比較好。
6.RocketMQ安裝步驟
①JDK的安裝與配置
從Oracle官網上下載最新的jdk-9.0.1,下載地址如下:
解壓到指定目錄:
tar -zxvf jdk-9.0.1_linux-x64_bin.tar.gz -C /usr/local/java
配置環境變數需要在/etc/profile檔案最下方新增以下內容即可:
儲存退出後,在命令列輸入Java -version檢視版本號,能查到說明JDK安裝配置成功。
②RocketMQ安裝配置
從Apache官網上下載RocketMQ的安裝包,下載地址如下:
我們下載二進位制編譯包即可:
將其上傳至伺服器,解壓到制定目錄:
unzip rocketmq-all-4.1.0-incubating-bin-release.zip
cp -r rocketmq-all-4.1.0-incubating /usr/local/rocketmq
rm -rf rocketmq-all-4.1.0-incubating
RocketMQ的檔案結構如下:
配置RocketMQ的環境變數,vi /etc/profile,在檔案底部新增以下內容:
NAMESRV_ADDR可以不在此繫結,但必須在啟動broker時加上“-n 伺服器IP:埠”以繫結nameserver,本次實驗就直接繫結以簡化操作,9876是nameserver的預設埠。
最後輸入以下命令source /etc/profile,使配置生效,RocketMQ的安裝及環境變數配置就完成了。
7.RocketMQ的部署
①Broker節點屬性配置
Broker節點的配置檔案在/rocketmq/conf下面,有三種配置方式:
2m-noslave: 多Master模式
2m-2s-sync: 多Master多Slave模式,同步雙寫
2m-2s-async:多Master多Slave模式,非同步複製
不同的模式有相對應的配置方法,部署多少叢集,就要相應建立多少個配置檔案,我們拿多Master模式舉例,進去會發現裡面有兩個檔案:
代表兩個Master,檢視原始檔案的內容:
裡面有若干引數配置,其餘均為預設配置,如果需要叢集配置,需根據實際情況設定相應引數,官網給出了Broker配置的引數列表:
文件地址是http://rocketmq.apache.org/docs/rmq-deployment/
特別強調的是:如果nameserver要叢集的話,要在namesrvAddr上列出所有nameserver節點的IP和埠;brokerRole要填寫當前節點的角色有ASYNC_MASTER、SYNC_MASTER、SLAVE三種。
配置例項請參考以下部落格:
②啟動nameserver
在ROCKET_HOME路徑下執行命令nohup sh mqnamesrv &
在啟動狀態執行查詢命令tail -f ~/logs/rocketmqlogs/namesrv.log
從中可以看出nameserver啟動成功。
③啟動broker
在ROCKET_HOME路徑下執行命令nohup sh mqbroker &
如果沒有註冊NAMESRV_ADDR執行nohup sh mqbroker -n伺服器IP:9876 &
如有多個broker的配置檔案,則還要加上啟動哪個broker的配置檔案,如:
nohup sh mqbroker -n 伺服器IP:9876 -c $ROCKETMQ_HOME/conf/2m-noslave/broker-a.properties &
需要注意的是broker啟動需要的記憶體較大,我設定虛擬機器的時候只分配了2G記憶體,啟動時報記憶體不足異常,通過cat nohup.out命令查得以下日誌資訊:
我們需要修改記憶體資訊,執行檢視命令cat runbroker.sh,找到# JVM Configuration處檢視JAVA_OPT設定,如下圖:
-Xms的值已經遠大於記憶體和交換區的大小,我們用命令cat runserver.sh檢視一下nameserver的記憶體配置,nameserver正常啟動幾乎把記憶體佔滿,
所以我們應把nameserver和broker的記憶體都改小,當然在實際開發環境部署時也可以根據實際需求將其改大。
Nameserver的配置如下:
Broker的配置如下:
分別啟動nameserver和broker,
執行命令tail -f ~/logs/rocketmqlogs/broker.log檢視broker的啟動狀態:
說明我們啟動broker成功,broker在nameserver上也註冊成功。
④關閉nameserver和broker
關閉nameserver在ROCKETMQ_HOME路徑下執行以下命令:
sh mqshutdown namesrv
關閉broker在ROCKETMQ_HOME路徑下執行以下命令:
sh mqshutdown broker
一般先關閉所有的broker後,再關閉nameserver。
⑤測試
RocketMQ有自帶的除錯工具模擬Producer和Consumer
在ROCKETMQ_HOME路徑下執行以下命令模擬Producer發訊息:
sh tools.sh org.apache.rocketmq.example.quickstart.Producer
會發出很多條下面的命令,說明發送成功:
在ROCKETMQ_HOME路徑下執行以下命令模擬Consumer發訊息:
sh tools.sh org.apache.rocketmq.example.quickstart.Consumer
會收到和上面一樣多的命令,說明接收成功,可證明RocketMQ部署成功:
8.建立Producer和Consumer
RocketMQ可支援多種訊息,如一般訊息、定時訊息、廣播訊息、順序訊息等,詳細參見官方文件,有程式碼例項,本次只列出一種訊息的例項。
①新增依賴
以下依賴是必須的:
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>rocketmq-common</artifactId>
<exclusions>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<scope>test</scope>
</dependency>
</dependencies
②建立Producer
注:producer在使用之前需先設定nameserver的地址才能和RocketMQ通訊,即:producer.setNamesrvAddr("伺服器IP:9876");
③建立Consumer
注:consumer在使用之前需先設定nameserver的地址才能和RocketMQ通訊,即:consumer.setNamesrvAddr("伺服器IP:9876");
還有更高階的推拉訊息的用法,可以從GitHub上得到原始碼,檢視rocketmq-master\client中的Producer和Consumer的程式碼。