高可用架構篇:【2】ActiveMQ高可用+負載均衡集羣的安裝、配置、高可用(多節點)

ActiveMQ高可用+負載均衡集羣的安裝、配置、高可用[ZooKeeper + LevelDB + Static discovery](多節點)

前言:從ActiveMQ 5.9開始,ActiveMQ的集羣實現方式取消了傳統的Master-Slave方式,增加了基於ZooKeeper + LevelDB的Master-Slave實現方式,其他兩種方式目錄共享和數據庫共享依然存在。

一、三種集羣方式的對比:

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

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

(2)基於JDBC:

<bean id="mysql-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<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.0.222:2181,192.168.0.223:2182,192.168.0.224:2183
主機 集羣端口 消息端口 管控臺端口 節點安裝目錄
192.168.0.222 62621 51511 8161 /home/hk/activemq/node-01
192.168.0.223 62622 51512 8162 /home/hk/activemq/node-02
192.168.0.224 62623 51513 8163 /home/hk/activemq/node-03

2、防火牆打開對應的端口

## node-01
-A INPUT -m state --state NEW -m tcp -p tcp --dport 8161 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 51511 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 61621 -j ACCEPT
## node-02
-A INPUT -m state --state NEW -m tcp -p tcp --dport 8162 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 51512 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 61622 -j ACCEPT
## node-03
-A INPUT -m state --state NEW -m tcp -p tcp --dport 8163 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 51513 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 61623 -j ACCEPT

3、分別在三臺主機中創建/home/hk/activemq目錄

$ mkdir /home/hk/activemq
上傳apache-activemq-5.11.1-bin.tar.gz到/home/hk/activemq目錄

4、解壓並按節點命名

$ cd /home/hk/activemq
$ tar -xvf apache-activemq-5.11.1-bin.tar.gz
$ mv apache-activemq-5.11.1 node-0X   #(X代表節點號1、2、3,下同)

5、修改管理控制檯端口(默認爲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.0.222:2181,192.168.0.223:2182,192.168.0.224: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.0.222:2181,192.168.0.223:2182,192.168.0.224: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.0.222:2181,192.168.0.223:2182,192.168.0.224:2183"
			hostname="edu-zk-03"
			zkPath="/activemq/leveldb-stores"
		/>
	</persistenceAdapter>
</broker>

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

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&amp;wireFormat.maxFrameSize=104857600"/>
   <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
   <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
   <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
   <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&amp;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&amp;wireFormat.maxFrameSize=104857600"/>
   <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
   <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
   <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
   <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&amp;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&amp;wireFormat.maxFrameSize=104857600"/>
   <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
   <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
   <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
   <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
</transportConnectors>

7、按順序啓動3個ActiveMQ節點:

$ /home/hk/activemq/node-01/bin/activemq start
$ /home/hk/activemq/node-02/bin/activemq start
$ /home/hk/activemq/node-03/bin/activemq start
監聽日誌:
$ tail -f /home/hk/activemq/node-01/data/activemq.log
$ tail -f /home/hk/activemq/node-02/data/activemq.log
$ tail -f /home/hk/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.0.222:51511,tcp://192.168.0.223:51512,tcp://192.168.0.224:51513)?randomize=false

10、集羣高可用測試

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

11、設置開機啓動:

# vi /etc/rc.local
## activemq
su - hk -c 'cd /home/hk/activemq/node-01/bin/ && ./activemq start'
su - hk -c 'cd /home/hk/activemq/node-02/bin/ && ./activemq start'
su - hk -c 'cd /home/hk/activemq/node-03/bin/ && ./activemq start'

12、配置優化

  • updateURIsURL,通過URL(或者本地路徑)獲取重連的url,這樣做具有良好的擴展性,因爲客戶端每次連接都是從URL(或文件)中加載一次,所以可以隨時從文件中更新url列表,做到動態添加MQ的備點。
  • failover:()?randomize=false&updateURIsURL=file:/home/hk/activemq/urllist.txt
  • urllist.txt中的地址通過英文逗號分隔,示例:
  • tcp://192.168.0.222:51511,tcp://192.168.0.223:51512,tcp://192.168.0.224:51513
  • 最後,附上官方文檔的一則警告,請使用者注意。replicatedLevelDB不支持延遲或者計劃任務消息。這些消息存儲在另外的LevelDB文件中,如果使用延遲或者計劃任務消息,將不會複製到slave Broker上,不能實現消息的高可用。

三、負載均衡集羣

主要配置【需要自己再手動搭一套集羣

  • 本人搭建一套僞集羣【ip:192.168.0.225】

集羣1鏈接集羣2:

# vi activemq.xml
<broker>
	<networkConnectors>
		<networkConnector uri="static:(tcp://192.168.0.225:53531,tcp://192.168.0.225:53532,tcp://192.168.0.225:53533)" duplex="false"/>
	</networkConnectors>
</broker>

集羣2鏈接集羣1:

# vi activemq.xml
<broker>
	<networkConnectors>
		<networkConnector uri="static:(tcp://192.168.0.222:51511,tcp://192.168.0.223:51512,tcp://192.168.0.224:51513)" duplex="false"/>
	</networkConnectors>
</broker>

自行模擬高可用及負載均衡場景測試【點擊下載測試代碼

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