1. 程式人生 > >ActiveMQ叢集配置及使用

ActiveMQ叢集配置及使用

為什麼要對訊息中介軟體叢集?

實現高可用,以排除單點故障引起的服務中斷

實現負載均衡,以提升效率為更多使用者提供服務

叢集方式:

客戶端叢集:讓多個消費者消費同一個佇列

Broker clusters:多個Broker之間同步訊息

Master Slave:實現高可用

客戶端配置:

ActiveMQ失效轉移(falilover):

允許當其中一臺訊息伺服器宕機時,客戶端在傳輸層上重新連線到其他訊息伺服器。

語法:failover:(uri1,....,uriN)?transportOptions

transportOptions引數說明:

randomize:預設為true,表示在URI列表中選擇URI連線時是否採用隨機策略

initialReconnectDelay:預設10毫秒,表示第一次嘗試重連之間等待的時間

maxReconnectDelay:預設30000毫秒,表示最長重連的時間間隔

Broker clusters叢集配置:

原理:兩個節點,節點A和節點B,節點A可以把訊息同步到節點B,節點B可以把訊息同步到節點A,同步之後,節點A接收到的訊息可以被節點B的消費者消費,反之亦然,其實現方式是通過"網路聯結器"來實現的。

網路聯結器:網路聯結器主要用於配置ActiveMQ伺服器與伺服器之間的網路通訊方式,用於伺服器透傳訊息。又分為靜態聯結器和動態聯結器。

靜態聯結器配置:

<networkConnectors>

<networkConnector uri="static:(tcp://127.0.0.1:61617,tcp://127.0.0.1:61618)"/>

</networkConnectors>

動態聯結器配置:

<networkConnectors>

<networkConnector uri="multicast://default"/>

</networkConnectors>

<transportConnectors>

<transportConnector uri="tcp://localhost:0" discoveryUri="multicast://default

"/>

</transportConnectors>

Master Slave叢集配置:

ActiveMQ Master Slave叢集方案:

1.Shared storage master/slave 共享儲存

2.Replicated LevelDB Store 基於複製的LevelDB Store 

共享儲存叢集的原理:

比如有兩臺伺服器節點A和節點B,他們有一個共享的持久化地址,先啟動節點A,A獲得排它鎖獨佔資源成為Master,B成為Slave,若A掛掉,B將獲得持久化資源的排它鎖成為Master接收客戶端的請求,客戶端通過失效轉移將請求傳送到了B,完成了請求的不間斷性,達到高可用效果。

基於複製的LevelDB Store的原理:

 因為LevelDB是基於ZK的,所以它的伺服器至少有三個,每個節點都有自己的儲存化方式,他們共有一個zk節點,通過zk來選取一臺伺服器作為Master,A就具有了提供給外部服務的能力,獲得外部訊息資源後在本地"store"儲存,再通過zk將訊息同步給B和C儲存起來,若A故障,zk會選取另一臺伺服器成為Master。


兩種叢集方式的對比


Master/Slave實現了高可用,因為一臺伺服器掛掉,另一臺伺服器可以馬上頂替上去,且保證了訊息不會丟失,但是無法做到負載均衡,因為Slave伺服器不能提供服務。

Broker Cluster不能實現高可用,因為它獲得的訊息沒有做持久化,若某個伺服器掛掉,它正在處理的訊息就會丟失,但是做到了負載均衡,因為A節點的訊息可以被節點B的消費者消費,B節點的訊息可以被節點A的消費者消費。

如何做到兩者兼備呢?

下面是網上找的一種三臺伺服器的完美叢集方案:
無論A,B,C哪個伺服器宕機,都不會影響服務的正常執行,保證了高可用,又因為B、C和A之間的訊息同步,實現了B、A或C、A之間可以互相消費彼此的訊息,實現了負載均衡。

ActiveMQ三臺伺服器的完美叢集具體配置方案:

因為只有一臺電腦,所以只能通過開放不同埠的方法來實現一臺電腦部署三個伺服器


先新建三個actvemq服務目錄activemq-A,activemq-B,activemq-C,一個持久化目錄share-DB


將apache-activemq-5.14.2複製進A,B,C三個目錄中

進入activemq-A的apache-activemq-5.14.2的conf,編輯activemq.xml


將除了埠61616的配置註釋掉


新增網路聯結器配置,將B,C的uri新增進來:


還需要編輯conf目錄下的jetty.xml(提供後端管理地址的jetty伺服器)


因為A節點使用的就是預設的8161埠,因此不用修改

以下是B節點activemq.xml的配置:

這是持久化目錄的配置

  <persistenceAdapter>
            <kahaDB directory="/opt/app/actvemq/share-DB"/>
        </persistenceAdapter>
網路聯結器的配置:
 <transportConnector name="openwire" uri="tcp://0.0.0.0:61617?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>
        <networkConnectors>
                <networkConnector name="network_A" uri="static:(tcp://127.0.0.1:61616)"/>
        </networkConnectors>
jetty服務埠則改為8162

C節點配置就不一一展示了,模仿B節點修改就行。

最後依次啟動A,B,C節點,檢視相應埠,可以看出因為先啟動activemq-B所以它成為Master,C節點成為Slave不提供服務(程序狀態TiIME_WAIT)


用我的部落格"簡單使用ActiveMQ"裡的程式碼進行測試,不過還要進行客戶端失效轉移的配置,很簡單就修改兩處地方:

AppPoducer.java:

 private static final String url="failover:(tcp://127.0.0.1:61617,tcp://127.0.0.1:61618)?randomize=true";  

AppConsumer.java:
 private static final String url="failover:(tcp://127.0.0.1:61616,tcp://127.0.0.1:61617,tcp://127.0.0.1:61618)?randomize=true";