ActiveMQ集羣部署與應用

本文主要講解ActiveMQ的集羣部署及主從切換演示,單機版部署及入門請移步ActiveMQ(一)單機部署與應用,本篇內容需要使用zookeeper集羣做支撐,未搭建zookeeper集羣的朋友請看我的另一篇文章zookeeper單機-集羣安裝詳解

簡介

在高併發、對穩定性要求極高的系統中,高可用的是必不可少的,當然ActiveMQ也有自己的集羣方案。從ActiveMQ 5.9開始,ActiveMQ的集羣實現方式取消了傳統的Master-Slave方式,增加了基於ZooKeeper + LevelDB 的 Master-Slave 實現方式

ActiveMQ3種集羣方式對比

(一)基於共享文件系統(KahaDB,默認)

 

<persistenceAdapter>
 <kahaDB directory="${activemq.data}/kahadb"/>
</persistenceAdapter>

activemq.xml默認

(二)基於JDBC持久化

 

<persistenceAdapter>
<jdbcPersistenceAdapter dataSource="#MySQL-DS"/>
</persistenceAdapter>
<!--注意:需要添加mysql-connector-java相關的jar包到avtivemq的lib包下-->
<bean id="MySQL-DS" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/platform_mq?useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="xxxx"/>
</bean>

(三)基於可複製的LevelDB(google開發類庫,非服務)

 

<persistenceAdapter>
  <replicatedLevelDB directory="${activemq.data}/leveldb" #數據存儲路徑
replicas="3" #節點個數
bind="tcp://0.0.0.0:62621" #用於各個節點之間的通訊
zkAddress="localhost:2181,localhost:2182,localhost:2183"
hostname="localhost"
zkPath="/activemq/leveldb-stores"/>#在zookeeper中集羣相關數據存放路徑
</persistenceAdapter>

本文主要講解基於ZooKeeper和LevelDB搭建ActiveMQ集羣,集羣僅提供集羣功能,避免單點故障,沒有負載均衡功能,負載均衡後續更新

高可用原理

使用ZooKeeper(集羣)註冊所有的ActiveMQ Broker。只有其中的一個Broker可以提供服務,被視爲Master,其他的Broker(節點)處於待機狀態,被視爲Slave。如果Master因故障而不能提供服務,ZooKeeper會從Slave中選舉出一個Broker充當Master
Slave連接Master並同步他們的存儲狀態,Slave不接受客戶端連接。所有的存儲操作都將被複制到連接至Master的Slaves。如果Master宕了,得到了最新的Slave會成爲Master。故障節點在回覆後會重新加入到集羣中並連接Master進入Slave模式。

所有需同步的disk的消息操作都將等待存儲狀態被複制到其他法定節點的操作完成才能完成。所以,如果你配置了replicas=3,那麼法定大小是(3/2)+1=2。Master將會存儲並更新然後等待(2-1)=1個Slave存儲和更新完成,才彙報success。至於爲什麼是2-1,熟悉Zookeeper的應該知道,有一個node要作爲觀察者存在。當一個新的Master被選中,你需要至少保障一個法定node在線以能夠找到擁有最新狀態的node。這個node可以成爲新的Master。因此,推薦運行至少3個replica nodes,以防止一個node失敗了,服務中斷。(原理與Zookeeper集羣的高可用實現方式類似)

Mq只有Master提供Client服務

集羣部署

. 規劃

環境:CentOS7_64、JDK7
版本:ActiveMQ 5.9
ZooKeeper集羣環境:192.168.2.10:2181、 192.168.2.30:2182 、192.168.40:2183

主機 集羣端口 消息端口 管控臺端口 節點安裝目錄
192.168.2.10 62621 51511 8161 /home/lenovo/install/activemq-01
192.168.2.30 62622 51512 8162 /home/lenovo/install/activemq-03
192.168.2.40 62623 51513 8163 /home/lenovo/install/activemq-04

1、 防火牆打開對應端口
2、 在3臺虛擬機中部署好單節點的mq
3、 修改管理控制檯端口(默認爲8161)可在conf/jetty.xml中修改,如下:

 

#activemq-01
<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
         <!-- the default port number for the web console -->
    <property name="host" value="0.0.0.0"/>
    <property name="port" value="8161"/>
</bean>

#activemq-02
<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
         <!-- the default port number for the web console -->
    <property name="host" value="0.0.0.0"/>
    <property name="port" value="8162"/>
</bean>

#activemq-03
<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
         <!-- the default port number for the web console -->
    <property name="host" value="0.0.0.0"/>
    <property name="port" value="8163"/>
</bean>

4、集羣配置
在3個ActiveMQ節點配置conf/activemq.xml持久化適配器。修改其中bind、zkAddress、hostname和zkPath。注意:每個activemq的BrokerName必須相同,否則不能加入集羣。

在原有的基礎上修改即可

修改brokerName爲platform_app(可改可不改)
最爲重要的是修改persistenceAdapter部分,將其默認的註釋,加入如下:

 

#activemq-01
<persistenceAdapter>
<!--kahaDB directory="${activemq.data}/kahadb"/ -->
<replicatedLevelDB
directory="${activemq.data}/leveldb"
replicas="3"
bind="tcp://0.0.0.0:62621"
zkAddress="192.168.2.10:2181,192.168.2.30:2182,192.168.2.40:2183"
hostname="lenovo1" zkPath="/activemq/leveldb-stores"/>
</persistenceAdapter>

#activemq-02
<persistenceAdapter>
<!--kahaDB directory="${activemq.data}/kahadb"/ -->
<replicatedLevelDB
directory="${activemq.data}/leveldb"
replicas="3"
bind="tcp://0.0.0.0:62622"
zkAddress="192.168.2.10:2181,192.168.2.30:2182,192.168.2.40:2183"
hostname="lenovo3" zkPath="/activemq/leveldb-stores"/>
</persistenceAdapter>

#activemq-03
<persistenceAdapter>
<!--kahaDB directory="${activemq.data}/kahadb"/ -->
<replicatedLevelDB
directory="${activemq.data}/leveldb"
replicas="3"
bind="tcp://0.0.0.0:62623"
zkAddress="192.168.2.10:2181,192.168.2.30:2182,192.168.2.40:2183"
hostname="lenovo4" zkPath="/activemq/leveldb-stores"/>
</persistenceAdapter>

修改各節點的消息端口(注意:避免端口衝突)

 

 #activemq-01:改爲51511
    <transportConnectors>
        <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
        <transportConnector name="openwire" uri="tcp://0.0.0.0:51511?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
        <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
        <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
        <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
        <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
    </transportConnectors>

#activemq-02:改爲51512
    <transportConnectors>
        <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
        <transportConnector name="openwire" uri="tcp://0.0.0.0:51512?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
        <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
        <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
        <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
        <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
    </transportConnectors>

 #activemq-03:改爲51513
    <transportConnectors>
        <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
        <transportConnector name="openwire" uri="tcp://0.0.0.0:51513?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
        <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
        <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
        <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
        <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
    </transportConnectors>

啓動服務並監聽日誌(需先啓動zookeeper集羣服務)

 

[lenovo@localhost bin]$ activemq-01/bin/activemq start
[lenovo@localhost bin]$ activemq-02/bin/activemq start
[lenovo@localhost bin]$ activemq-03/bin/activemq start

[lenovo@localhost bin]$ tail -f activemq-01/data/activemq.log
[lenovo@localhost bin]$ tail -f activemq-02/data/activemq.log
[lenovo@localhost bin]$ tail -f activemq-03/data/activemq.log

輸出如下INFO信息則表示配置成功

日誌信息

集羣節點分析

運行zookeeper工具進行監控,查看集羣抓取圖,工具我已上傳至:鏈接:http://pan.baidu.com/s/1pL0k1vH 密碼:yufo
本地若配置了java環境可以直接運行build下的jar

隨機連接一臺服務

 

連接後下圖可以看到ActiveMQ有3個節點,其中0000000000節點的elected值不爲空且address路徑也不爲空,可以確定爲是master,這裏3臺的文件路徑爲之前設置的zkPath,app_id是之前設置好了的“platform_app”

 

master節點

slave節點

web管理控制檯查看

下面3臺機器中我們只能查看一臺master服務器能訪問,原理在介紹部分說過,所有的slave只有複製功能,一旦master宕機,slave選舉出的master將能夠訪問,這裏我就不做測試了

 

8161端口服務——很明顯爲slave節點

8162端口服務——也爲slave節點

8163端口服務——master節點

高可用測試

注:我的另外一篇文章有講述該測試項目的結構,這裏我將項目配置修改便於測試,集羣代碼地址:鏈接:http://pan.baidu.com/s/1nuANGnf 密碼:p5dk

java代碼配置failover連接

 

ActiveMQ的客戶端只能訪問Master的Broker,其他處於slave的broker不能訪問。所以客戶端連接Broker使用failover(失敗轉移)協議,即誰正常就連誰。

接下來開啓,MQConsumer監聽,使用MQProducerTest每隔300ms發一次消息

消息發送測試

Consumer成功連接master

不斷髮送信息

 

然後不斷刷新管控臺,這時就能看到消息不斷被消費掉

 

管控臺在不斷刷新消費

接下來我們進行高可用測試,使master宕機,然後觀察日誌信息

master宕機後快速選舉出新的master

 

上圖我們可以看到,宕機後新的master被選舉出來,通過打印信息可以看到業務數據沒有任何丟失的情況

刷新監控工具,master已經被成功選舉

觀察管控臺可以看到http ://192.168.2.40:8163/不能進行訪問,http ://192.168.2.30:8162/能夠進行訪問,因爲master被重新進行選舉,所以8162端口成爲了master

注:這裏只剩下兩臺機器,若此時出現繼續宕機的情況,那麼slave將不能進行選舉。

現在讓宕機的那臺機器重新恢復,讓它繼續加入集羣充當slave角色

刷新監控工具查看

 

當一個ActiveMQ節點掛掉,或者一個ZooKeeper節點掛掉,ActiveMQ服務依然正常運轉。如果僅剩一個ActiveMQ節點,因爲不能選舉Master,ActiveMQ不能正常運轉;同樣的,如果ZooKeeper僅剩一個節點活動,不管ActiveMQ各節點是否存活,ActiveMQ也不能正常提供服務。
(ActiveMQ集羣的高可用,依賴於ZooKeeper集羣的高可用。)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章