ActiveMQ(二)ActiveMQ集群部署與應(yīng)用

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

簡介

在高并發(fā)、對穩(wěn)定性要求極高的系統(tǒng)中,高可用的是必不可少的,當(dāng)然ActiveMQ也有自己的集群方案。從ActiveMQ 5.9開始,ActiveMQ的集群實(shí)現(xiàn)方式取消了傳統(tǒng)的Master-Slave方式,增加了基于ZooKeeper + LevelDB 的 Master-Slave 實(shí)現(xiàn)方式

ActiveMQ3種集群方式對比

(一)基于共享文件系統(tǒng)(KahaDB,默認(rèn))

<persistenceAdapter>
 <kahaDB directory="${activemq.data}/kahadb"/>
</persistenceAdapter>
activemq.xml默認(rèn)

(二)基于JDBC持久化

<persistenceAdapter>
<jdbcPersistenceAdapter dataSource="#MySQL-DS"/>
</persistenceAdapter>
<!--注意:需要添加mysql-connector-java相關(guān)的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>

(三)基于可復(fù)制的LevelDB(google開發(fā)類庫,非服務(wù))

<persistenceAdapter>
  <replicatedLevelDB directory="${activemq.data}/leveldb" #數(shù)據(jù)存儲(chǔ)路徑
replicas="3" #節(jié)點(diǎn)個(gè)數(shù)
bind="tcp://0.0.0.0:62621" #用于各個(gè)節(jié)點(diǎn)之間的通訊
zkAddress="localhost:2181,localhost:2182,localhost:2183"
hostname="localhost"
zkPath="/activemq/leveldb-stores"/>#在zookeeper中集群相關(guān)數(shù)據(jù)存放路徑
</persistenceAdapter>

本文主要講解基于ZooKeeper和LevelDB搭建ActiveMQ集群,集群僅提供集群功能,避免單點(diǎn)故障,沒有負(fù)載均衡功能,負(fù)載均衡后續(xù)更新

高可用原理

使用ZooKeeper(集群)注冊所有的ActiveMQ Broker。只有其中的一個(gè)Broker可以提供服務(wù),被視為Master,其他的Broker(節(jié)點(diǎn))處于待機(jī)狀態(tài),被視為Slave。如果Master因故障而不能提供服務(wù),ZooKeeper會(huì)從Slave中選舉出一個(gè)Broker充當(dāng)Master
Slave連接Master并同步他們的存儲(chǔ)狀態(tài),Slave不接受客戶端連接。所有的存儲(chǔ)操作都將被復(fù)制到連接至Master的Slaves。如果Master宕了,得到了最新的Slave會(huì)成為Master。故障節(jié)點(diǎn)在回復(fù)后會(huì)重新加入到集群中并連接Master進(jìn)入Slave模式。

所有需同步的disk的消息操作都將等待存儲(chǔ)狀態(tài)被復(fù)制到其他法定節(jié)點(diǎn)的操作完成才能完成。所以,如果你配置了replicas=3,那么法定大小是(3/2)+1=2。Master將會(huì)存儲(chǔ)并更新然后等待(2-1)=1個(gè)Slave存儲(chǔ)和更新完成,才匯報(bào)success。至于為什么是2-1,熟悉Zookeeper的應(yīng)該知道,有一個(gè)node要作為觀察者存在。當(dāng)一個(gè)新的Master被選中,你需要至少保障一個(gè)法定node在線以能夠找到擁有最新狀態(tài)的node。這個(gè)node可以成為新的Master。因此,推薦運(yùn)行至少3個(gè)replica nodes,以防止一個(gè)node失敗了,服務(wù)中斷。(原理與Zookeeper集群的高可用實(shí)現(xiàn)方式類似)

Mq只有Master提供Client服務(wù)

集群部署

. 規(guī)劃

環(huán)境:CentOS7_64、JDK7
版本:ActiveMQ 5.9
ZooKeeper集群環(huán)境:192.168.2.10:2181、 192.168.2.30:2182 、192.168.40:2183

主機(jī) 集群端口 消息端口 管控臺(tái)端口 節(jié)點(diǎn)安裝目錄
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、 防火墻打開對應(yīng)端口
2、 在3臺(tái)虛擬機(jī)中部署好單節(jié)點(diǎn)的mq
3、 修改管理控制臺(tái)端口(默認(rèn)為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個(gè)ActiveMQ節(jié)點(diǎn)配置conf/activemq.xml持久化適配器。修改其中bind、zkAddress、hostname和zkPath。注意:每個(gè)activemq的BrokerName必須相同,否則不能加入集群。

在原有的基礎(chǔ)上修改即可

修改brokerName為platform_app(可改可不改)
最為重要的是修改persistenceAdapter部分,將其默認(rèn)的注釋,加入如下:

#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>

修改各節(jié)點(diǎn)的消息端口(注意:避免端口沖突)

 #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>

啟動(dòng)服務(wù)并監(jiān)聽日志(需先啟動(dòng)zookeeper集群服務(wù))

[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信息則表示配置成功

日志信息

集群節(jié)點(diǎn)分析

運(yùn)行zookeeper工具進(jìn)行監(jiān)控,查看集群抓取圖,工具我已上傳至:鏈接:http://pan.baidu.com/s/1pL0k1vH 密碼:yufo
本地若配置了java環(huán)境可以直接運(yùn)行build下的jar

隨機(jī)連接一臺(tái)服務(wù)

連接后下圖可以看到ActiveMQ有3個(gè)節(jié)點(diǎn),其中0000000000節(jié)點(diǎn)的elected值不為空且address路徑也不為空,可以確定為是master,這里3臺(tái)的文件路徑為之前設(shè)置的zkPath,app_id是之前設(shè)置好了的“platform_app”


master節(jié)點(diǎn)
slave節(jié)點(diǎn)
web管理控制臺(tái)查看

下面3臺(tái)機(jī)器中我們只能查看一臺(tái)master服務(wù)器能訪問,原理在介紹部分說過,所有的slave只有復(fù)制功能,一旦master宕機(jī),slave選舉出的master將能夠訪問,這里我就不做測試了


8161端口服務(wù)——很明顯為slave節(jié)點(diǎn)
8162端口服務(wù)——也為slave節(jié)點(diǎn)
8163端口服務(wù)——master節(jié)點(diǎn)

高可用測試

注:我的另外一篇文章有講述該測試項(xiàng)目的結(jié)構(gòu),這里我將項(xiàng)目配置修改便于測試,集群代碼地址:鏈接:http://pan.baidu.com/s/1nuANGnf 密碼:p5dk

java代碼配置failover連接

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

接下來開啟,MQConsumer監(jiān)聽,使用MQProducerTest每隔300ms發(fā)一次消息

消息發(fā)送測試
Consumer成功連接master
不斷發(fā)送信息

然后不斷刷新管控臺(tái),這時(shí)就能看到消息不斷被消費(fèi)掉


管控臺(tái)在不斷刷新消費(fèi)

接下來我們進(jìn)行高可用測試,使master宕機(jī),然后觀察日志信息

master宕機(jī)后快速選舉出新的master

上圖我們可以看到,宕機(jī)后新的master被選舉出來,通過打印信息可以看到業(yè)務(wù)數(shù)據(jù)沒有任何丟失的情況

刷新監(jiān)控工具,master已經(jīng)被成功選舉

觀察管控臺(tái)可以看到http ://192.168.2.40:8163/不能進(jìn)行訪問,http ://192.168.2.30:8162/能夠進(jìn)行訪問,因?yàn)閙aster被重新進(jìn)行選舉,所以8162端口成為了master

注:這里只剩下兩臺(tái)機(jī)器,若此時(shí)出現(xiàn)繼續(xù)宕機(jī)的情況,那么slave將不能進(jìn)行選舉。

現(xiàn)在讓宕機(jī)的那臺(tái)機(jī)器重新恢復(fù),讓它繼續(xù)加入集群充當(dāng)slave角色

刷新監(jiān)控工具查看

當(dāng)一個(gè)ActiveMQ節(jié)點(diǎn)掛掉,或者一個(gè)ZooKeeper節(jié)點(diǎn)掛掉,ActiveMQ服務(wù)依然正常運(yùn)轉(zhuǎn)。如果僅剩一個(gè)ActiveMQ節(jié)點(diǎn),因?yàn)椴荒苓x舉Master,ActiveMQ不能正常運(yùn)轉(zhuǎn);同樣的,如果ZooKeeper僅剩一個(gè)節(jié)點(diǎn)活動(dòng),不管ActiveMQ各節(jié)點(diǎn)是否存活,ActiveMQ也不能正常提供服務(wù)。
(ActiveMQ集群的高可用,依賴于ZooKeeper集群的高可用。)

以上內(nèi)容為參考網(wǎng)絡(luò)教程親自試驗(yàn)后的情況,希望能幫助到真正學(xué)習(xí)的朋友

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、ActiveMQ集群的簡單介紹 從 ActiveMQ 5.9 開始,ActiveMQ 的集群實(shí)現(xiàn)方式取消了傳統(tǒng)...
    會(huì)跳舞的機(jī)器人閱讀 3,770評論 0 18
  • 人生是海洋,希望是舵手的羅盤,使人們在暴風(fēng)雨中不致迷失方向。 —— 狄德羅 1. 前言 ??ActiveMQ M...
    guqj閱讀 4,162評論 0 0
  • 1 Zookeeper概述# ZooKeeper是一個(gè)為分布式應(yīng)用所設(shè)計(jì)的分布的、開源的協(xié)調(diào)服務(wù),它主要是用來解決...
    七寸知架構(gòu)閱讀 7,486評論 0 101
  • 在hyperledger fabric的orderer中,目前發(fā)布的版本是使用kafka來做排序,并沒有用到所謂的...
    y9g閱讀 6,969評論 0 3
  • 從 ActiveMQ 5.9 開始,ActiveMQ 的集群實(shí)現(xiàn)方式取消了傳統(tǒng)的Master-Slave 方式,增...
    曹振華閱讀 967評論 0 0

友情鏈接更多精彩內(nèi)容