簡述
activemq提供了多種方式來保證activemq的可靠性。
包括:
- 純Master/Slave
- Shared File System Master Slave
- JDBC Master Slave
- Broker clusters-靜態
- Broker clusters-動態(基於組播,動態發現brokers)
但單純的使用上面的一種沒法既達到高可用,同時有具有負載均衡的能力。
生產環境集羣搭建建議
所以可以考慮Master/Slave+Broker clusters-靜態來實現。Master/Slave保證了Slave複製master的數據,Broker clusters-靜態實現了非消息生產者的broker擁有對外提供消費的能力。即在broker1上生產了消息,如果broker1與broker2配置了static network Connectors,那麼客戶端監聽broker2也可以拿到broker1生產的消息。所以生產環境建議二者集合。
生產環境:
-
如果數據量不大,可以考慮Zookeeper來搭建Master/Slave。
由於ZK選舉至少需要2N+1個節點,所以mq至少要3個節點。如果生產消息的broker掛掉,ZK會從其他的節點選擇一個作爲Master。客戶端使用failover會自動連接到提升爲Master的節點,消費掛掉的broker的消息沒有問題。 -
數據量比較大,考慮Zookeeper+靜態網絡連接來實現高可用與負載均衡能力。
比如2個ZK(假定分別爲zk1和zk2),每個ZK分別管理1組(3臺)MQ節點。這樣啓動全部的MQ節點,2組MQ節點中會分別有1臺Master對外提供服務。然後2組MQ之間通過static network Connectors+duplex=true來實現failover功能。
配置1:
[外鏈圖片轉存失敗(img-xJpGT9p6-1566178835980)(https://app.yinxiang.com/shard/s64/nl/13987728/a5337336-4489-482f-9cde-5531127a51a2/res/7ae0ffda-501f-40be-a4f1-19823127319b.png?resizeSmall&width=832)]
這種配置,一個缺點就是沒有保障ZK的高可用。
如果希望ZK也高可用,則每組ZK至少配置3個ZK節點(ZN+1原則)。
比如下面的配置2組ZK+2組MQ。
作用 | openwire端口 | admin端口 | zk端口 | 組 |
---|---|---|---|---|
mq1 | 61616 | 8161 | zk1,2,3的2181,2182,2183 | Group1 |
mq2 | 61617 | 8162 | zk1,2,3的2181,2182,2183 | Group1 |
mq3 | 61618 | 8163 | zk1,2,3的2181,2182,2183 | Group1 |
mq4 | 61616 | 8161 | zk4,5,6的2181,2182,2183 | Group2 |
mq5 | 61617 | 8162 | zk4,5,6的2181,2182,2183 | Group2 |
mq6 | 61618 | 8163 | zk4,5,6的2181,2182,2183 | Group2 |
zk1 | / | / | 2181 | Group1 |
zk2 | / | / | 2182 | Group1 |
zk3 | / | / | 2183 | Group1 |
zk4 | / | / | 2181 | Group2 |
zk5 | / | / | 2182 | Group2 |
zk6 | / | / | 2183 | Group2 |
這裏假定Group1和Group2是2臺機器,ZK1和ZK2爲2臺機器。其中,mq1-3爲Group1,zkAddress=zk1:2181,zk2:2182,zk3:2183.mq4-6爲Group2,zkAddress=zk4:2181,zk5:2182,zk6:2183.注意:6臺MQ的brokerName必須全部一樣。
當然了,你還可以繼續擴展,比如3組ZK+3組MQ,這樣同時對外提供服務的MQ就是3臺。
關鍵配置
1.ZK集羣搭建
那一組ZK來說
在該組ZK的根目錄創建data目錄,然後創建3個子目錄,名字分別爲1,2,3,在每個子目錄下面創建myid文件,內容與目錄名字相同(即如果屬於目錄1,則內容爲1)。
在每個ZK節點的配置文件zoo.cfg中最後加入:
server.1=127.0.0.1:2887:3887
server.2=127.0.0.1:2888:3888
server.3=127.0.0.1:2889:3889
每個ZK節點的dataDir指向它所屬的data目錄。比如ZK1的dataDir=/usr/local/zookeeper/data/1。其中/usr/local/zookeeper是該組ZK集羣的根目錄。
2.ActiveMQ集羣配置
打開activemq.xml,修改或加入如下內容:
- 修改brokerName;
- 中的內容爲:
<persistenceAdapter>
<!-- <kahaDB directory="${activemq.data}/kahadb"/>-->
<replicatedLevelDB
directory="${activemq.data}/leveldb"
replicas="3"
bind="tcp://0.0.0.0:0"
zkAddress="127.0.0.1:2181,127.0.0.1:2181,127.0.0.1:2183"
zkPassword=""
zkPath="/activemq-cluster/leveldb-stores/group1"
hostname="vm1"
sync="local_disk"/>
此處需注意:replicas是MQ節點的數量,需要爲2N+1.zkAddress指定ZK集羣的地址,多個地址用逗號分隔,zkPath保證不與其他ZK組的path一樣(如果2組ZK在不同的機器可以忽略),否則會導致選舉Master出現問題,因爲各個ZK組都查找到了相同的節點。
- 修改transportConnector
<transportConnectors>
<!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
</transportConnectors>
一個是修改openwrie的端口,然後把其他協議的註釋掉。(這裏根據需要,只保留使用的協議)。
4. 增加static network Connector配置
<networkConnectors>
<networkConnector uri="static:(tcp://192.168.199.199:61619,tcp://192.168.199.199:61620,tcp://192.168.199.199:61621)" duplex="true" />
</networkConnectors>
這裏的IP和端口是其他Group的IP和端口。因爲你希望在Group1生產的數據在Group2的節點能夠消費,反之亦然。所以這裏配置的是其他組的IP和端口。另外,需要配置duplex=true。否則,比如Group1的mq1生產消息,然後停止mq1,此時消費者連接上Group2,是沒法消費消息的。配置上duplex=true,就可以保證在Group2也能消費到Group1生產的消息。反之亦然。
-
修改每個mq的管理端口
修改jetty.xml中的port即可。 -
應用程序配置
程序使用failover來連接broker。
比如:
final static String uris =
"failover:(tcp://192.168.199.199:61616,tcp://192.168.199.199:61617,tcp://192.168.199.199:61618," +
"tcp://192.168.199.199:61619,tcp://192.168.199.199:61620,tcp://192.168.199.199:61621)" +
"?randomize=true&initialReconnectDelay=1000&maxReconnectDelay=30000";
final static String MQ_USERNAME = "admin";
final static String MQ_PASSWORD = "admin";
上面配置完畢後,先啓動各個ZK,沒問題再啓動各個MQ節點。觀察日誌輸出,每組ZK只會有一個是Master,其他是Slave。每組MQ只會有一個是Master,其他是Slave。
配置完畢後,將MQ的openwire的端口對外開放,程序就可以訪問了。
集羣測試
-
測試某組MQ節點之間數據是否正常(測試Master/Slave功能);
生產者和消費者都使用failover連接所有MQ節點,生產者發送消息。消息發送完畢後,將發送消息的MQ節點停掉,然後消費者連接發送消息的MQ所在組的其他MQ節點,看是否正常消費消息。
比如Group1節點分別爲mq1,mq2,mq3,假定發送消息的MQ節點是mq1,那麼發送消息完畢後,停掉mq1.然後啓動消費者,看消費者能否消費消息。這裏生產者和消費者都使用failover連接mq1,mq2,mq3. -
測試組間數據是否正常(測試Static NetWork Connector功能)。
生產者與#1一致,發送消息後關閉該mq節點。消費者使用failover連接另外一組MQ,看是否能夠消費消息。
都使用failover連接mq1,mq2,mq3.
- 測試組間數據是否正常(測試Static NetWork Connector功能)。
生產者與#1一致,發送消息後關閉該mq節點。消費者使用failover連接另外一組MQ,看是否能夠消費消息。
各種MQ集羣配置參考:ActiveMQ集羣搭建詳解