天天看點

ActiveMQ高可用叢集部署方案

1.概述

1.1簡介

ActiveMQ是分布式系統中重要的元件,主要解決應用耦合、異步消息、流量削鋒等問題,是大型分布式系統不可缺少的中間件。在生産環境中為了保證讓ActiveMQ能夠持續工作,我們還需要為消息中間件服務搭建叢集環境,進而在保證消息中間件服務可靠性和處理性能。

1.2叢集模式概述

叢集模式主要是為了解決ActiveMQ系統架構中的兩個關鍵問題:高可用和高性能。

針對上述兩種需求,AActiveMQ主要有如下兩種叢集模式分别對應:

  • Master-slave模式
  • Broker-Cluster模式

1.2.1Master-slave模式

Master-Slave叢集由至少3個節點組成,一個Master節點,其他為Slave節點。隻有Master節點對外提供服務,Slave節點處于等待狀态。當主節點當機後,從節點會推舉出一個節點出來成為新的Master節點,繼續提供服務。

ActiveMQ高可用叢集部署方案

Master-Slave模式的部署方式,主要分為三種:

  • Shared Filesystem Master-Slave方式,如KahaDB,應用靈活、高效且安全。
  • Shared Database Master-Slave方式,基于共享資料庫,跟第一種類似,性能會受限于資料庫。
  • Replicated LevelDB Store方式,基于zookeeper + leveldb。是生産環境常用的方案。

1.2.2Broker-Cluster模式

Broker-Cluster部署方式中,各個broker通過網絡互相連接配接,自動分發調用端請求,進而實作叢集的負載均衡。Broker-Cluster叢集連接配接到網絡代理的方式,主要分為靜态網絡代理、動态網絡代理,不同的網絡代理方式也對應了不同的叢集部署方式:

  • static Broker-Cluster
  • Dynamic Broker-Cluster

    在實際應用場景中static Broker-Cluster被大量使用。

ActiveMQ高可用叢集部署方案

靜态網絡代理示意圖

1.3叢集部署規劃

1.3.1叢集架構

Master-Slave叢集的優點是可以解決多服務熱備的高可用問題,但缺點是無法解決負載均衡和分布式的問題。Broker-Cluster叢集的優點是可以解決負載均衡和分布式的問題,但不支援高可用。

是以,把Master-Slave和Broker-Cluster兩者相結合,就可以得到一個完美的解決方案:即又可以做到叢集負載均衡又可以做到任何一個broker如果發生當機,也不會影響提供服務,節點消息也不會“丢失”。

在這裡我們可以選擇部署6個ActiveMQ執行個體,把6個ActiveMQ執行個體分成兩組(Group)。Group1的三個節點通過Master-Slave模式組成brokerA,group2的3個節點通過Master-Slave模式組成brokerB,并使得brokerA與brokerB組成Broker-Cluster叢集。

ActiveMQ高可用叢集部署方案

1.3.2伺服器規劃

一般情況下,生産環境需要多個ActiveMQ配置在多台伺服器中,但是由于本次環境搭建僅用于學習測試,且本地環境的機器規格受限,是以接下來我們将會在兩個docker容器中進行模拟,每個容器以3組端口運作3個ActiveMQ執行個體。因為是在一台機器上做實驗,即使運作兩個docker容器,也需要在主控端映射對應的端口。是以不同的ActiveMQ執行個體需要有不同的端口配置,具體配置設定如下:

節點 IP openwire端口 admin端口
mq1 172.18.0.112 61616 8161
mq2 61617 8162
mq3 61618 8163
mq4 172.18.0.116 61619 8164
mq5 61620 8165
mq6 61621 8166

2.環境準備

2.1容器及網絡環境準備

1.拉取centos7鏡像

docker pull centos:7           

2.建立自定義docker網絡

預設情況下啟動的Docker容器,都是使用bridge網絡,容器重新開機時,docker的IP就會發生改變,且不支援為容器指定固定IP。

是以我們需要基于bridge建立自定義網絡。

docker network create --subnet=172.18.0.0/16 qqnetwork           

3.建立activemq所需容器

docker run -i -t --name mqbrokerAA -p 61616:61616 -p 61617:61617 -p 61618:61618 -p 8161:8161 -p 8162:8162 -p 8163:8163 --privileged=true --net qqnetwork --ip 172.18.0.112 -d centos:7

docker run -i -t --name mqbrokerBB -p 61619:61619 -p 61620:61620 -p 61621:61621 -p 8164:8164 -p 8165:8165 -p 8166:8166 --privileged=true --net qqnetwork --ip 172.18.0.116 -d centos:7           

2.2Java環境

ActiveMQ運作前需要確定已經安裝配置jdk8的環境,這部分資料有很多,這裡不再贅述。

3.叢集部署

3.1搭建Master-Slave叢集

3.1.1安裝ActiveMQ

1.在/usr/local目錄下建立mqcluster目錄,然後在該目錄中建立mq1,mq2,mq3的檔案夾。

ActiveMQ高可用叢集部署方案

2.将apache-activemq-5.15.3-bin.tar.gz壓縮包的内容解壓到這三個目錄。

tar -zxvf apache-activemq-5.15.12-bin.tar.gz -C /usr/local/mqcluster/           

3.分别單獨運作3個ActiveMQ執行個體,保證單獨運作正常。

3.1.2配置叢集

3.1.2.1配置節點名

ActiveMQ Master-Slave叢集的broker必須有統一的brokername,在這裡需要修改ACTIVEMQ_HOME/conf/activemq.xml檔案,将3個節點的brokerName統一為“brokerA”。

<broker xmlns="http://activemq.apache.org/schema/core" brokerName="brokerA" dataDirectory="${activemq.data}">           
3.1.2.2持久化配置

ActiveMQ的持久化主要有如下幾種方案:

  • 基于日志檔案存儲,如KahaDB
  • JDBC消息存儲,如使用mysql将消息持久化
  • LevelDB消息存儲

    這裡采用KahaDB的方式,原理就是讓參與高可用的所有節點共用一個資料檔案目錄,通過檔案鎖的方式來決定誰是master誰是slave。在這裡需要做的就是将3個節點的資料目錄配置成相同的即可。

修改ACTIVEMQ_HOME/conf/activemq.xml檔案,3個節點均修改成如下配置即可。

<persistenceAdapter>
     <kahaDB directory="/usr/local/mqcluster/mq1/data/kahadb"/>
</persistenceAdapter>           
3.1.2.3TCP端口配置

實驗環境暫時隻用到tcp,是以隻配置openwire,暫時将其它的端口配置注釋掉。openwire預設為61616,同一個容器内端口不能重複,否則端口沖突,是以需要将mq1,mq2,mq3分别對應端口61616,61617,61618。

該配置也在ACTIVEMQ_HOME/conf/activemq.xml, 具體修改如下:

<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
           
<transportConnector name="openwire" uri="tcp://0.0.0.0:61617?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>           
<transportConnector name="openwire" uri="tcp://0.0.0.0:61618?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>           
3.1.2.4Jetty端口配置

ActiveMQ使用jetty運作服務,與openwire同理,3個節點運作的端口必須不同。修改ACTIVEMQ_HOME/conf/jetty.xml,3個節點依次改為8161,8162,8163。

<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>           
<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>           
<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>           

3.1.3啟動叢集

至此,ActiveMQ高可用叢集已經配置好了,然後分别啟動mq1,mq2,mq3執行個體。

/usr/local/mqcluster/mq1/bin/activemq start
/usr/local/mqcluster/mq2/bin/activemq start
/usr/local/mqcluster/mq3/bin/activemq start           

如果配置正常,在後啟動的兩個節點的啟動日志中會輸出如下日志,表示已經有master鎖定,自己将以slave角色運作。

注意:隻有master節點接受請求,slave不接受請求,也無法使用管理界面。

3.2搭建Broker-Cluster叢集

3.2.1搭建第二組Master-Slave叢集

上面我們已經搭建好了一個Master-Slave叢集,但僅僅是master-slave的話隻能保證高可用,卻無法做到負載均衡,如果mq因負載過大挂掉, master-slave也無法解決這種問題,是以就必須配置Broker-Cluster模式實作ActiveMQ叢集的負載均衡。

此時,可以按照上述方式及前期的叢集規劃依次安裝配置mq4/mq5/mq6,即可完成另一個Master-Slave叢集。

3.2.2配置Broker-Cluster叢集

Broker-Cluster部署方式中,“靜态方式”在實際應用場景中被大量使用,是以我們這裡采用靜态uri方式,具體操作如下所示。

1.在group1中所有的節點修改ACTIVEMQ_HOME/conf/activemq.xml檔案,添加如下配置連結group2(在persistenceAdapter标簽前配置):

<networkConnectors>
    <networkConnector name="brokerB" uri="static:(tcp://172.18.0.116:61619,tcp://172.18.0.116:61620,tcp://172.18.0.116:61621)" duplex="true" />
</networkConnectors>           

需要注意,broker-cluster模式duplex預設為false,這種情況下broker-cluster可以實作消息分發,但消息隻存在一個broker上。與此同時,也就意味着,一旦broker當機,則可能會出現消息丢失。

這裡我們配置duplex="true",當這個節點使用Network Bridge連接配接到其它目标節點後,将強制目标也建立Network Bridge進行反向連接配接。其目的在于讓消息既能發送到目标節點,又可以通過目标節點接受消息。它相當于下面幾行的效果:

<!-- 在group1中 -->  
<networkConnector name="group1-broker1" uri="static:(tcp://172.18.0.116:61619)" duplex="false" />  
<!-- 在group1中 -->  
<networkConnector name="group1-broker2" uri="static:(tcp://172.18.0.116:61620)" duplex="false" />  
<!-- 在group1中 -->  
<networkConnector name="group1-broker3" uri="static:(tcp://172.18.0.116:61621)" duplex="false" /> 
 
 
<!-- 在group2中 -->  
<networkConnector name="group2-broker1" uri="static:(tcp://172.18.0.112:61616)" duplex="false" />  
<!-- 在group2中 -->  
<networkConnector name="group2-broker2" uri="static:(tcp://172.18.0.112:61617)" duplex="false" />  
<!-- 在group2中 -->  
<networkConnector name="group2-broker3" uri="static:(tcp://172.18.0.112:61618)" duplex="false" />           

2.上一步配置duplex="true"後,group2中所有的節點則不需要再修改ACTIVEMQ_HOME/conf/activemq.xml檔案,也不需要再連結group1。

到這裡,我們就已經完成了ActiveMQ高可用+負載均衡的叢集搭建。在下一篇文章我們将結合Java工程,完成對本次搭建的ActiveMQ系統的功能驗證、高可用及負載均衡功能驗證。