ActiveMQ 5.9版本提供了基於LevelDB的高可用方式,包括數據的高可用和服務的高可用,一站式提供全套服務,很方便。java
服務高可用的原理:使用zookeeper(集羣)註冊全部的ActiveMQ Broker。只有其中的一個Broker能夠提供服務,被視爲master,其餘的Broker處於待機狀態,被視爲slave。當master因爲死機等緣由,不能提供服務,zookeeper會從slave中選舉出一個Broker充當master。當原來的master Broker恢復繼續提供服務的能力時,從新註冊入zookeeper集羣,做爲slave待機。node
這時ActiveMQ的客戶端只能訪問master的Broker,其餘處於slave的Broker不能訪問。因此客戶端鏈接Broker應該使用failover協議。apache
failover:(tcp://broker1:61616,tcp://broker2:61616,tcp://broker3:61616)
這樣即便當前的master Broker死機,zookeeper切換另外一臺機器爲master,客戶端也不須要重啓和修改代碼,徹底透明。安全
下面是對zookeeper數據的抓圖,能夠看到activemq的有3個節點,分別是00000000033,00000000034,00000000032。這個圖展示了00000000033的值,能夠看到elected的值是null,代表這個節點是slave。tcp
而master節點的數據內容以下圖,能夠看到elected的值是明確的寫着00000000032,是被選舉的master節點。性能
消息數據高可用原理:消息的操做會用同步的方式複製到全部的集羣內的Broker中,一直阻塞到知足高可用,纔會完成本次消息操做。知足消息高可用的條件是設置replicas值。舉例說明,若是值設置爲3,則高可用節點的法定數量 (3/2+1)=2個節點,消息會被master Broker存儲到本地,而且至少存儲到另外一個遠程的節點,必須2個節點都複製了消息,纔算是消息安全存儲。也就是說,若是replicas=3,說明當前是3個節點的集羣。若是有1個節點不可用,不影響集羣,能夠繼續提供服務。可是若是2個節點不可用,雖然還有1個節點是好的,可是因爲能夠提供服務的節點數量小於高可用的法定節點數量,則整個集羣將不可用。測試
配置以下:spa
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="DemoBroker" dataDirectory="${activemq.data}"> <persistenceAdapter> <replicatedLevelDB directory="activemq-data" replicas="3" bind="tcp://0.0.0.0:0" zkAddress="zoo1.example.org:2181,zoo2.example.org:2181,zoo3.example.org:2181" zkPassword="password" zkPath="/activemq/leveldb-stores" hostname="broker1.example.org" /> </persistenceAdapter> ...其餘配置 </broker>
這裏有一個配置點是須要注意的,我曾經在這裏出錯卡住過兩小時。就是每一個集羣的brokerName必須一致,不然就不會加到同一個集羣裏。用官方文檔的原話就是:All the broker nodes that are part of the same replication set should have matching brokerName
XML attributes. code
下面是一個簡單的性能測試結果,用以對比複製的LevelDB和單機LevelDB的性能差距orm
能夠看出,發送消息性能差2-3倍,消費消息性能相差很少。
發送1000條消息(毫秒) | 發送10000條消息(毫秒) | 消費1000條消息的時間(毫秒) | 消費10000條消息的時間(毫秒) | |
replicatedLevelDB(3節點) | 89138 | 611313 | 306 | 2628 |
LevelDB | 34032 | 347712 | 220 | 2877 |
最後,附上官方文檔的一則警告,請使用者注意。replicatedLevelDB不支持延遲或者計劃任務消息。這些消息存儲在另外的LevelDB文件中,若是使用延遲或者計劃任務消息,將不會複製到slave Broker上,不能實現消息的高可用。