1. 程式人生 > >RocketMQ部署開發

RocketMQ部署開發

前言

RocketMQ是阿里巴巴團隊研發的高效能、分散式訊息中介軟體,已捐贈給Apache基金會,面向所有開發人員開源免費使用,本文主要參考其官方快速文件(http://jm.taobao.org/2017/01/12/rocketmq-quick-start-in-10-minutes/)和自己親自動手實踐,我們從瞭解RocketMQ開始,循序漸進,一步一步親自實現中介軟體部署,測試訊息收發,從理論和實踐兩方面學會使用RocketMQ

1.RocketMQ 是什麼?

上圖是一個典型的訊息中介軟體收發訊息的模型,RocketMQ也是這樣的設計,簡單說來,RocketMQ具有以下特點:

是一個佇列模型的訊息中介軟體,具有高效能、高可靠、高實時、分散式特點。

Producer、Consumer、佇列都可以分散式。

Producer向一些佇列輪流傳送訊息,佇列集合稱為Topic,Consumer如果做廣播消費,則一個consumer例項消費這個Topic對應的所有佇列,如果做叢集消費,則多個Consumer例項平均消費這個topic對應的佇列集合。

能夠保證嚴格的訊息順序

提供豐富的訊息拉取模式

高效的訂閱者水平擴充套件能力

實時的訊息訂閱機制

億級訊息堆積能力

較少的依賴

2.RocketMQ 物理部署結構

如上圖所示, RocketMQ的部署結構有以下特點:

Name Server是一個幾乎無狀態節點,可叢集部署,節點之間無任何資訊同步。

Broker部署相對複雜,Broker分為Master與Slave,一個Master可以對應多個Slave,但是一個Slave只能對應一個Master,Master與Slave的對應關係通過指定相同的BrokerName,不同的BrokerId來定義,BrokerId為0表示Master,非0表示Slave。Master也可以部署多個。每個Broker與Name Server叢集中的所有節點建立長連線,定時註冊Topic資訊到所有Name Server。

Producer與Name Server叢集中的其中一個節點(隨機選擇)建立長連線,定期從Name Server取Topic路由資訊,並向提供Topic服務的Master建立長連線,且定時向Master傳送心跳。Producer完全無狀態,可叢集部署。

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,本次實驗就直接繫結以簡化操作,9876nameserver的預設埠。

最後輸入以下命令source /etc/profile,使配置生效,RocketMQ的安裝及環境變數配置就完成了。

7.RocketMQ的部署

Broker節點屬性配置

Broker節點的配置檔案在/rocketmq/conf下面,有三種配置方式:

 

2m-noslave: 多Master模式

2m-2s-sync: 多MasterSlave模式,同步雙寫

2m-2s-async:多MasterSlave模式,非同步複製

不同的模式有相對應的配置方法,部署多少叢集,就要相應建立多少個配置檔案,我們拿多Master模式舉例,進去會發現裡面有兩個檔案:

 

代表兩個Master,檢視原始檔案的內容:

 

裡面有若干引數配置,其餘均為預設配置,如果需要叢集配置,需根據實際情況設定相應引數,官網給出了Broker配置的引數列表:

 

文件地址是http://rocketmq.apache.org/docs/rmq-deployment/

特別強調的是:如果nameserver要叢集的話,要在namesrvAddr上列出所有nameserver節點的IP和埠;brokerRole要填寫當前節點的角色有ASYNC_MASTERSYNC_MASTERSLAVE三種。

配置例項請參考以下部落格:

②啟動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中的ProducerConsumer的程式碼。