ActiveMQ高可用集羣安裝、配置、高可用測試html
(ZooKeeper + LevelDB)node
從ActiveMQ 5.9開始,ActiveMQ的集羣實現方式取消了傳統的Master-Slave方式,增長了基於ZooKeeper + LevelDB的Master-Slave實現方式,其餘兩種方式目錄共享和數據庫共享依然存在。mysql
三種集羣方式的對比:web
(1)基於共享文件系統(KahaDB,默認):sql
<persistenceAdapter>數據庫
<kahaDB directory="${activemq.data}/kahadb"/>apache
</persistenceAdapter>架構
(2)基於JDBC:負載均衡
<bean id="mysql-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">dom
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/amq?relaxAutoCommit=true"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<property name="maxActive" value="20"/>
<property name="poolPreparedStatements" value="true"/>
</bean>
<persistenceAdapter>
<jdbcPersistenceAdapter dataDirectory="${activemq.data}" dataSource="#mysql-ds"
createTablesOnStartup="false"/>
</persistenceAdapter>
(3)基於可複製的LevelDB(本教程採用這種集羣方式):
LevelDB是Google開發的一套用於持久化數據的高性能類庫。LevelDB並非一種服務,用戶須要自行實現Server。是單進程的服務,可以處理十億級別規模Key-Value型數據,佔用內存小。
<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"
/>
</persistenceAdapter>
本節課程主要講解基於ZooKeeper和LevelDB搭建ActiveMQ集羣。集羣僅提供主備方式的高可用集羣功能,避免單點故障,沒有負載均衡功能。
官方文檔:http://activemq.apache.org/replicated-leveldb-store.html
集羣原理圖:
高可用的原理:使用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集羣的高可用實現方式相似)
1、ActiveMQ集羣部署規劃:
環境:CentOS 6.6 x64 、 JDK7
版本:ActiveMQ 5.11.1
ZooKeeper集羣環境:192.168.1.81:2181,192.168.1.82:2182,192.168.1.83:2183
(ZooKeeper集羣部署請參考《高可用架構篇--第01節--ZooKeeper集羣的安裝、配置、高可用測試》)
主機 |
集羣端口 |
消息端口 |
管控臺端口 |
節點安裝目錄 |
192.168.1.81 |
62621 |
51511 |
8161 |
/home/wusc/activemq/node-01 |
192.168.1.82 |
62622 |
51512 |
8162 |
/home/wusc/activemq/node-02 |
192.168.1.83 |
62623 |
51513 |
8163 |
/home/wusc/activemq/node-03 |
2、防火牆打開對應的端口
3、分別在三臺主機中建立/home/wusc/activemq目錄
$ mkdir /home/wusc/activemq
上傳apache-activemq-5.11.1-bin.tar.gz到/home/wusc/activemq目錄
4、解壓並按節點命名
$ cd /home/wusc/activemq
$ tar -xvf apache-activemq-5.11.1-bin.tar.gz
$ mv apache-activemq-5.11.1 node-0X #(X表明節點號一、二、3,下同)
五、修改管理控制檯端口(默認爲8161)可在conf/jetty.xml中修改,以下:
Node-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>
Node-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>
Node-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>
6、集羣配置:
在3個ActiveMQ節點中配置conf/activemq.xml中的持久化適配器。修改其中bind、zkAddress、hostname和zkPath。注意:每一個ActiveMQ的BrokerName必須相同,不然不能加入集羣。
Node-01中的持久化配置:
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="DubboEdu" dataDirectory="${activemq.data}">
<persistenceAdapter>
<!-- kahaDB directory="${activemq.data}/kahadb"/ -->
<replicatedLevelDB
directory="${activemq.data}/leveldb"
replicas="3"
bind="tcp://0.0.0.0:62621"
zkAddress="192.168.1.81:2181,192.168.1.82:2182,192.168.1.83:2183"
hostname="edu-zk-01"
zkPath="/activemq/leveldb-stores"
/>
</persistenceAdapter>
</broker>
Node-02中的持久化配置:
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="DubboEdu" dataDirectory="${activemq.data}">
<persistenceAdapter>
<!-- kahaDB directory="${activemq.data}/kahadb"/ -->
<replicatedLevelDB
directory="${activemq.data}/leveldb"
replicas="3"
bind="tcp://0.0.0.0:62622"
zkAddress="192.168.1.81:2181,192.168.1.82:2182,192.168.1.83:2183"
hostname="edu-zk-02"
zkPath="/activemq/leveldb-stores"
/>
</persistenceAdapter>
</broker>
Node-03中的持久化配置:
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="DubboEdu" dataDirectory="${activemq.data}">
<persistenceAdapter>
<!-- kahaDB directory="${activemq.data}/kahadb"/ -->
<replicatedLevelDB
directory="${activemq.data}/leveldb"
replicas="3"
bind="tcp://0.0.0.0:62623"
zkAddress="192.168.1.81:2181,192.168.1.82:2182,192.168.1.83:2183"
hostname="edu-zk-03"
zkPath="/activemq/leveldb-stores"
/>
</persistenceAdapter>
</broker>
修改各節點的消息端口(注意,避免端口衝突):
Node-01中的消息端口配置:
<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>
Node-02中的消息端口配置:
<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>
Node-03中的消息端口配置:
<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>
7、按順序啓動3個ActiveMQ節點:
$ /home/wusc/activemq/node-01/bin/activemq start
$ /home/wusc/activemq/node-02/bin/activemq start
$ /home/wusc/activemq/node-03/bin/activemq start
監聽日誌:
$ tail -f /home/wusc/activemq/node-01/data/activemq.log
$ tail -f /home/wusc/activemq/node-02/data/activemq.log
$ tail -f /home/wusc/activemq/node-03/data/activemq.log
8、集羣的節點狀態分析:
集羣啓動後對ZooKeeper數據的抓圖,能夠看到ActiveMQ的有3個節點,分別是00000000000,00000000001,00000000002。
如下第一張圖展示了00000000000的值,能夠看到elected的值是不爲空,說明這個節點是Master,其餘兩個節點是Slave。
9、集羣可用性測試(配置和測試代碼,請看視頻):
ActiveMQ的客戶端只能訪問Master的Broker,其餘處於Slave的Broker不能訪問。因此客戶端鏈接Broker應該使用failover協議。
failover:(tcp://192.168.1.81:51511,tcp://192.168.1.82:51512,tcp://192.168.1.83:51513)?randomize=false
10、集羣高可用測試(請看視頻):
當一個ActiveMQ節點掛掉,或者一個ZooKeeper節點掛掉,ActiveMQ服務依然正常運轉。若是僅剩一個ActiveMQ節點,由於不能選舉Master,ActiveMQ不能正常運轉;一樣的,若是ZooKeeper僅剩一個節點活動,無論ActiveMQ各節點是否存活,ActiveMQ也不能正常提供服務。
(ActiveMQ集羣的高可用,依賴於ZooKeeper集羣的高可用。)
十一、設置開機啓動:
# vi /etc/rc.local
su - wusc -c '/home/wusc/activemq/node-01/bin/activemq start'
su - wusc -c '/home/wusc/activemq/node-02/bin/activemq start'
su - wusc -c '/home/wusc/activemq/node-03/bin/activemq start'
12、配置優化(可選):
updateURIsURL,經過URL(或者本地路徑)獲取重連的url,這樣作具備良好的擴展性,由於客戶端每次鏈接都是從URL(或文件)中加載一次,因此能夠隨時從文件中更新url列表,作到動態添加MQ的備點。
failover:()?randomize=false&updateURIsURL=file:/home/wusc/activemq/urllist.txt
urllist.txt中的地址經過英文逗號分隔,示例:
tcp://192.168.1.81:51511,tcp://192.168.1.82:51512,tcp://192.168.1.83:51513
最後,附上官方文檔的一則警告,請使用者注意。replicatedLevelDB不支持延遲或者計劃任務消息。這些消息存儲在另外的LevelDB文件中,若是使用延遲或者計劃任務消息,將不會複製到slave Broker上,不能實現消息的高可用。