ActiveMQ集群搭建


  集群方案主要為了解決系統架構中的兩個關鍵問題:高可用高性能。ActiveMQ服務的高可用性是指,在ActiveMQ服務性能不變、數據不丟失的前提下,確保當系統災難出現時ActiveMQ能夠持續提供消息服務,高可靠性方案最終目的是減少整個ActiveMQ停止服務的時間。

  ActiveMQ服務的高性能是指,在保證ActiveMQ服務持續穩定性、數據不丟失的前提下,確保ActiveMQ集群能夠在單位時間內吞吐更高數量的消息、確保ActiveMQ集群處理單條消息的時間更短、確保ActiveMQ集群能夠容納更多的客戶端穩定連接。

  下面我們分別介紹如何通過多個ActiveMQ服務節點集群方式,分別提供熱備方案和高性能方案。最后我們討論如何將兩種方案結合在一起,最終形成在生成環境下使用的推薦方案。

一、高可用集群

以下內容來自:

ActiveMQ+ZooKeeper 偽集群整合https://segmentfault.com/a/1190000014636822

ActiveMQ+ZooKeeper 集群整合https://segmentfault.com/a/1190000014635114

1.1、ActiveMQ+ZooKeeper 偽集群整合

偽集群方式,即在一台主機上部署3個activemq服務(端口不同)+3個zookeeper服務(端口不同)

原理簡介:
一般在部署ActiveMQ集群的時候,更傾向於使用基於ZooKeeper的Replicated LevelDB Store方式,該方式是Master Slave部署方案的其中一種策略,也是在多台主機實現ActiveMQ集群的主流部署方式。 這里只保證了高可用性。要想保證負載均衡得再結合Broker Clusters 部署方案,配置網絡連接器。

工作流程:
在ZooKeeper中管理多個Broker節點,根據 Master選舉策略讓其中一個 Broker選舉為Master(只有Master才具備對外提供服務的能力),剩下Broker為slave。
編碼時,client端(消費者)通過failover協議來連接ActiveMQ集群。

1.1.1、ZooKeeper偽集群配置

規划

-- 服務端口 集群通信端口 節點目錄/usr/local下
zk1 2181 2881:3881 /zookeeper/zk1
zk2 2182 2882:3882 /zookeeper/zk2
zk3 2183 2883:3883 /zookeeper/zk3

集群通信端口:第一個端口是master和slave之間的通信端口,默認是2881;第二個端口是leader選舉的端口,集群剛啟動的時候選舉或者leader掛掉之后進行新的選舉的端口默認是3881。

配置zoo.cfg文件,創建myid

zk1/conf/zoo.cfg:

# zookeeper的數據存儲和日志存儲目錄(如果目錄不存在就新建)
dataDir=/usr/local/zookeeper/zk1/data
dataLogDir=/usr/local/zookeeper/zk1/log

#服務端口
clientPort=2181

# zk集群之間的通信地址
server.1=localhost:2881:3881
server.2=localhost:2882:3882
server.3=localhost:2883:3883

 

創建zk1/data/myid文件,填入數字1:

# 由於該zk1是server.1,所以在myid中設置數字1
$ vim /usr/local/zookeeper/zk1/data/myid

 

zk2/conf/zoo.cfg:

# zookeeper的數據存儲和日志存儲目錄(如果目錄不存在就新建)
dataDir=/usr/local/zookeeper/zk1/data
dataLogDir=/usr/local/zookeeper/zk1/log #服務端口 clientPort=2182 # zk集群之間的通信地址 server.1=localhost:2881:3881 server.2=localhost:2882:3882 server.3=localhost:2883:3883

 

創建zk2/data/myid文件,填入數字2:

# 由於該zk1是server.2,所以在myid中設置數字2
$ vim /usr/local/zookeeper/zk1/data/myid

zk3/conf/zoo.cfg:

# zookeeper的數據存儲和日志存儲目錄(如果目錄不存在就新建)
dataDir=/usr/local/zookeeper/zk1/data
dataLogDir=/usr/local/zookeeper/zk1/log #服務端口 clientPort=2183 # zk集群之間的通信地址 server.1=localhost:2881:3881 server.2=localhost:2882:3882 server.3=localhost:2883:3883

 

創建zk3/data/myid文件,填入數字3:

# 由於該zk1是server.3,所以在myid中設置數字3
$ vim /usr/local/zookeeper/zk1/data/myid

 

啟動Zookeeper

$ /usr/local//zookeeper/zk1/bin/zkServer.sh start # 啟動zk1服務
$ /usr/local//zookeeper/zk2/bin/zkServer.sh start # 啟動zk2服務
$ /usr/local//zookeeper/zk3/bin/zkServer.sh start # 啟動zk3服務

$ /usr/local//zookeeper/zk1/bin/zkServer.sh status # 查看zk1服務狀態
$ /usr/local//zookeeper/zk2/bin/zkServer.sh status # 查看zk2服務狀態
$ /usr/local//zookeeper/zk3/bin/zkServer.sh status # 查看zk3服務狀態

 

 

1.1.2、ActiveMQ偽集群配置

規划

 

-- 服務端口 jetty控制台端口 節點目錄/usr/local/下
node1 61616 8161 /activemq/node1
node2 61617 8162 /activemq/node2
node3 61618 8163 /activemq/node3

對3個activemq服務,並分別配置它們的文件conf/activemq.xml和conf/jetty.xml:

conf/jetty.xml:

  • node1:

/usr/local//activemq/node1/conf/activemq.xml:

<!-- activemq支持5種協議:openwire、amqp、 stomp、mqtt、ws,這里我們只使用openwire協議,注釋其它協議 -->
<transportConnectors>
    <!-- node1服務端口使用默認端口61616 -->
    <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?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>

<!-- 持久化的部分為ZooKeeper集群連接地址-->  
<persistenceAdapter>  
    <replicatedLevelDB  
      directory="${activemq.data}/leveldb"  
      replicas="3"  
      bind="tcp://0.0.0.0:0"  
      zkAddress="localhost:2181,localhost:2182,localhost:2183"   
      zkPath="/usr/local//activemq/leveldb-stores"  
      hostname="localhost"  
      />  
</persistenceAdapter>
<!-- 
# directory: 存儲數據的路徑
# replicas:集群中的節點數【(replicas/2)+1公式表示集群中至少要正常運行的服務數量】,3台集群那么允許1台宕機, 另外兩台要正常運行  
# bind:當該節點成為master后,它將綁定已配置的地址和端口來為復制協議提供服務。還支持使用動態端口。只需使用tcp://0.0.0.0:0進行配置即可,默認端口為61616。 
# zkAddress:ZK的ip和port, 如果是集群,則用逗號隔開(這里作為簡單示例ZooKeeper配置為單點, 這樣已經適用於大多數環境了, 集群也就多幾個配置) 
# zkPassword:當連接到ZooKeeper服務器時用的密碼,沒有密碼則不配置。 
# zkPah:ZK選舉信息交換的存貯路徑,啟動服務后actimvemq會到zookeeper上注冊生成此路徑   
# hostname: ActiveMQ所在主機的IP
# 更多參考:http://activemq.apache.org/replicated-leveldb-store.html
-->

 

/usr/local//activemq/conf/jetty.xml:

<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
    <property name="host" value="0.0.0.0"/>
    <property name="port" value="8161"/> <!-- 在這里修改端口為8161,默認就是8161 -->
</bean>

 

  • node2

/usr/local//activemq/node2/conf/activemq.xml:

<transportConnectors>
    <!-- 服務端口改為61617 -->
    <transportConnector name="openwire" uri="tcp://0.0.0.0:61617?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
</transportConnectors>

<!-- 持久化的部分為ZooKeeper集群連接地址-->  
<persistenceAdapter>  
    <replicatedLevelDB  
      directory="${activemq.data}/leveldb"  
      replicas="3"  
      bind="tcp://0.0.0.0:0"  
      zkAddress="localhost:2181,localhost:2182,localhost:2183"   
      zkPath="/usr/local//activemq/leveldb-stores"  
      hostname="localhost"  
      />  
</persistenceAdapter>

/usr/local//activemq/conf/jetty.xml:

<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
    <property name="host" value="0.0.0.0"/>
    <property name="port" value="8162"/> <!-- 在這里修改端口為8162,默認是8161 -->
</bean>

 

  • node3

/usr/local//activemq/node3/conf/activemq.xml:

<transportConnectors>
    <!-- 服務端口改為61618 -->
    <transportConnector name="openwire" uri="tcp://0.0.0.0:61618?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
</transportConnectors>

<!-- 持久化的部分為ZooKeeper集群連接地址-->  
<persistenceAdapter>  
    <replicatedLevelDB  
      directory="${activemq.data}/leveldb"  
      replicas="3"  
      bind="tcp://0.0.0.0:0"  
      zkAddress="localhost:2181,localhost:2182,localhost:2183"   
      zkPath="/usr/local//activemq/leveldb-stores"  
      hostname="localhost"  
      />  
</persistenceAdapter>

 

/usr/local//activemq/node3/conf/jetty.xml:

<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
    <property name="host" value="0.0.0.0"/>
    <property name="port" value="8163"/> <!-- 在這里修改端口為8163,默認是8161 -->
</bean>

依次啟動activemq服務

$ /usr/local//activemq/node1/bin/activemq start # 啟動節點node1服務
$ /usr/local//activemq/node2/bin/activemq start # 啟動節點node2服務
$ /usr/local//activemq/node3/bin/activemq start # 啟動節點node3服務

$ ps -ef|grep activemq # 檢查進程是否運行,即activemq是否啟動成功
$ netstat -anp|grep 61616 # 查看服務端口61616,監聽情況
$ netstat -anp|grep 61617 # 查看服務端口61617,監聽情況
$ netstat -anp|grep 61618 # 查看服務端口61618,監聽情況

1.1.3、Client使用

該zookeeper+activemq的集群Master Slave部署方案,能夠提供(3-1)/2的容錯率,即3台服務器允許宕機一台,而不影響整個集群的對外提供服務。

編寫代碼連接時使用failover策略:

String url = failover:(tcp://192.168.8.201:61616,tcp://192.168.8.201:61617,tcp://192.168.8.201:61618)?initialReconnectDelay=1000

 

1.2、ActiveMQ+ZooKeeper 集群整合

使用的是真集群方式,准備三台主機,IP分別為192.168.8.201、192.168.8.202、192.168.8.203

原理簡介:
一般在部署ActiveMQ集群的時候,更傾向於使用基於ZooKeeper的Replicated LevelDB Store方式,該方式是Master Slave部署方案的其中一種策略,也是在多台主機實現ActiveMQ集群的主流部署方式。 此教程只保證了高可用性。要想保證負載均衡得再結合Broker Clusters 部署方案,配置網絡連接器。

工作流程:
在ZooKeeper中管理多個Broker節點,根據 Master選舉策略讓其中一個 Broker選舉為Master(只有Master才具備對外提供服務的能力),剩下Broker為slave。
編碼時,client端(消費者)通過failover協議來連接ActiveMQ集群。

1.2.1、zookeeper集群

ZooKeeper集群保證ZooKeeper本身的高可用性。

規划

主機IP 服務端口(默認) 集群通信端口 節點目錄/usr/local/下  
192.168.8.201 2181 2881:3881 zookeeper
192.168.8.202 2181 2881:3881 zookeeper
192.168.8.203 2181 2881:3881 zookeeper

集群通信端口:第一個端口是master和slave之間的通信端口,默認是2881;第二個端口是leader選舉的端口,集群剛啟動的時候選舉或者leader掛掉之后進行新的選舉的端口默認是3881。

在3台主機上都安裝zookeeper服務,/usr/local//zookeeper,並分別配置它們的文件conf/zoo.cfg:

  • 主機1(192.168.8.201)

/usr/local//zookeeper/conf/zoo.cfg:

# zookeeper的數據存儲和日志存儲目錄(如果目錄不存在就新建)
dataDir=/usr/local//zookeeper/data
dataLogDir=/usr/local//zookeeper/log

# zk集群之間的通信地址
server.1=192.168.8.201:2888:3888
server.2=192.168.8.202:2888:3888
server.3=192.168.8.203:2888:3888

 

創建/usr/local//zookeeper/data/myid文件,填入數字1:

# 由於該主機1(192.168.8.201)是server.1,所以在myid中設置數字1
$ vim /usr/local//zookeeper/data/myid

 

  • 主機2(192.168.8.202)

    /usr/local//zookeeper/conf/zoo.cfg:
    
    dataDir=/usr/local//zookeeper/data
    dataLogDir=/usr/local//zookeeper/log
    
    server.1=192.168.8.201:2881:3881
    server.2=192.168.8.202:2881:3881
    server.3=192.168.8.203:2881:3881

     

    創建/usr/local//zookeeper/data/myid文件,填入數字2:

    # 由於該主機2(192.168.8.202)是server.2,所以在myid中設置數字2
    $ vim /usr/local//zookeeper/data/myid

     

  • 主機3(192.168.8.202)

    /usr/local//zookeeper/conf/zoo.cfg:
    
    dataDir=/usr/local//zookeeper/data
    dataLogDir=/usr/local//zookeeper/log
    
    server.1=192.168.8.201:2881:3881
    server.2=192.168.8.202:2881:3881
    server.3=192.168.8.203:2881:3881

    創建/usr/local//zookeeper/data/myid文件,填入數字3:

    # 由於該主機3(192.168.8.203)是server.3,所以在myid中設置數字3
    $ vim /usr/local//zookeeper/data/myid

     

分別啟動zookeeper服務

 
$ /usr/local//zookeeper/bin/zkServer.sh start # 啟動zk服務
$ /usr/local//zookeeper/bin/zkServer.sh status # 查看zk服務狀態

 1.2.2、ActiveMQ集群

規划

主機IP 服務端口(默認) 復制協議端口(動態) jetty控制台端口(默認) 節點目錄/usr/local/下  
192.168.8.201 61616 tcp://0.0.0.0:0 8161 activemq/node1
192.168.8.202 61616 tcp://0.0.0.0:0 8161 activemq/node2
192.168.8.203 61616 tcp://0.0.0.0:0 8161 activemq/node3

 
        

修改ActiveMQ配置文件conf/activemq.xmlconf/jetty.xml

在3台主機上都安裝activemq 服務,/usr/local//activemq,並分別配置它們的文件conf/activemq.xml和conf/jetty.xml:

  • 主機1(192.168.8.201)

/usr/local//activemq/conf/activemq.xml:

<!-- 持久化的部分為ZooKeeper集群連接地址-->  
<persistenceAdapter>  
    <replicatedLevelDB  
      directory="${activemq.data}/leveldb"  
      replicas="3"  
      bind="tcp://0.0.0.0:0"  
      zkAddress="192.168.8.201:2181,192.168.8.202:2181,192.168.8.203:2181"   
      zkPath="/usr/local//activemq/leveldb-stores"  
      hostname="192.168.8.201"  
      />  
</persistenceAdapter>
<!-- 
# directory: 存儲數據的路徑
# replicas:集群中的節點數【(replicas/2)+1公式表示集群中至少要正常運行的服務數量】,3台集群那么允許1台宕機, 另外兩台要正常運行  
# bind:當該節點成為master后,它將綁定已配置的地址和端口來為復制協議提供服務。還支持使用動態端口。只需使用tcp://0.0.0.0:0進行配置即可,默認端口為61616。 
# zkAddress:ZK的ip和port, 如果是集群,則用逗號隔開(這里作為簡單示例ZooKeeper配置為單點, 這樣已經適用於大多數環境了, 集群也就多幾個配置) 
# zkPassword:當連接到ZooKeeper服務器時用的密碼,沒有密碼則不配置。 
# zkPah:ZK選舉信息交換的存貯路徑,啟動服務后actimvemq會到zookeeper上注冊生成此路徑   
# hostname: ActiveMQ所在主機的IP
# 更多參考:http://activemq.apache.org/replicated-leveldb-store.html
-->

/usr/local//activemq/conf/jetty.xml:

<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
    <property name="host" value="0.0.0.0"/>
    <property name="port" value="8161"/> <!-- 在這里修改端口為8161,默認就是8161 -->
</bean>

 

  • 主機2(192.168.8.202)

    /usr/local//activemq/conf/activemq.xml:
    
    <persistenceAdapter>  
        <replicatedLevelDB  
          directory="${activemq.data}/leveldb"  
          replicas="3"  
          bind="tcp://0.0.0.0:0"  
          zkAddress="192.168.8.201:2181,192.168.8.202:2181,192.168.8.203:2181"   
          zkPath="/usr/local//activemq/leveldb-stores"  
          hostname="192.168.8.202"  
          />  
    </persistenceAdapter>

     

  /usr/local//activemq/conf/jetty.xml:

<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
    <property name="host" value="0.0.0.0"/>
    <property name="port" value="8161"/> <!-- 在這里修改端口為8161,默認就是8161 -->
</bean>

 

  • 主機3(192.168.8.203)
/usr/local//activemq/conf/activemq.xml:

<persistenceAdapter>  
    <replicatedLevelDB  
      directory="${activemq.data}/leveldb"  
      replicas="3"  
      bind="tcp://0.0.0.0:0"  
      zkAddress="192.168.8.201:2181,192.168.8.202:2181,192.168.8.203:2181"   
      zkPath="/usr/local//activemq/leveldb-stores"  
      hostname="192.168.8.203"  
      />  
</persistenceAdapter>

/usr/local//activemq/conf/jetty.xml:

<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
    <property name="host" value="0.0.0.0"/>
    <property name="port" value="8161"/> <!-- 在這里修改端口為8161,默認就是8161 -->
</bean>

依次啟動activemq服務

$ /usr/local//activemq/bin/activemq start # 啟動activemq服務

$ ps -ef|grep activemq # 檢查進程是否運行,即activemq是否啟動成功
$ netstat -anp|grep 61616 # 查看服務端口61616,監聽情況

1.2.3、Client使用

該zookeeper+activemq的集群Master Slave部署方案,能夠提供(3-1)/2的容錯率,即3台服務器允許宕機一台,而不影響整個集群的對外提供服務。

編寫代碼連接時使用failover策略:

 

String url = failover:(tcp://192.168.8.201:61616,tcp://192.168.8.202:61616,tcp://192.168.8.203:61616)?initialReconnectDelay=1000

 

二、負載均衡集群

以下內容來自:https://blog.csdn.net/yinwenjie/article/details/51124749

  ActiveMQ的多節點集群方案,主要有動態集群靜態集群兩種方案。

  • 動態集群:是指同時提供消息服務的ActiveMQ節點數量、位置(IP和端口)是不確定的,當某一個節點啟動后,會通過網絡組播的方式向其他節點發送通知(同時接受其他節點的組播信息)。當網絡中其他節點收到組播通知后,就會向這個節點發起連接,最終將新的節點加入ActiveMQ集群;

  • 靜態集群:是指同時提供消息服務的多個節點的位置(IP和端口)是確定的,每個節點不需要通過廣播的方式發現目標節點,只需要在啟動時按照給定的位置進行連接。

 

 

  • 靜態集群方案 

  •  動態集群方案

  

2.1、橋接Network Bridges

   為了實現ActiveMQ集群的橫向擴展要求和高穩定性要求,ActiveMQ集群提供了Network Bridges功能。通過Network Bridges功能,技術人員可以將多個ActiveMQ服務節點連接起來。並讓它們通過配置好的策略作為一個整體對外提供服務。

這樣的服務策略主要包括兩種:主/從模式負載均衡模式。對於第一種策略請看博文ActiveMQ筆記(3):基於Networks of Brokers的HA方案(http://www.cnblogs.com/leihenqianshang/articles/5623841.html)。這里我們要重點討論的是基於Network Bridges的負載均衡模式。

 

2.2、動態Network Connectors

   已經清楚了ActiveMQ中的動態節點發現原理和ActiveMQ Network Bridges的概念,那么關於ActiveMQ怎樣配置集群的方式就是非常簡單的問題了。我們先來討論如何進行基於組播發現的ActiveMQ負載均衡模式的配置——動態網絡連接Network Connectors;再來討論基於固定地址的負載均衡模式配置——靜態網絡連接Network Connectors

要配置基於組播發現的ActiveMQ負載均衡模式,其過程非常簡單。開發人員只需要在每一個ActiveMQ服務節點的主配置文件中(activemq.xml),添加/更改 以下配置信息即可:

 

......
<transportConnectors>
    <!-- 在transportConnector中增加discoveryUri屬性,表示這個transportConnector是要通過組播告知其它節點的:使用這個transportConnector位置連接我 -->
    <transportConnector name="auto" uri="auto+nio://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600&amp;org.apache.activemq.transport.nio.SelectorManager.corePoolSize=20&amp;org.apache.activemq.transport.nio.SelectorManager.maximumPoolSize=50&amp;consumer.prefetchSize=5" discoveryUri="multicast://239.0.0.5" />
</transportConnectors>

......

<!-- 關鍵的networkConnector標簽, uri屬性標示為組播發現-->
<networkConnectors>
    <networkConnector uri="multicast://239.0.0.5" duplex="false"/>
</networkConnectors>

......

 

2.2.1、 networkConnector標簽

如果使用ActiveMQ的組播發現功能,請在networkConnector標簽的uri屬性中添加如下格式的信息:

multicast://[組播地址][:端口]

 

例如,您可以按照如下方式使用ActiveMQ默認的組播地址來發現網絡種其他ActiveMQ服務節點:

#ActiveMQ集群默認的組播地址(239.255.2.3):
multicast://default

 

也可以按照如下方式,指定一個組播地址——這在高安全級別的網絡中很有用,因為可能其他的組播地址已經被管理員禁用。注意組播地址只能是D類IP地址段:

#使用組播地址239.0.0.5
multicast://239.0.0.5

 

 以下是通過抓包軟件獲得的的組播UDP報文

 

從上圖中我們可以獲得幾個關鍵信息:

  • 192.168.61.138和192.168.61.139這兩個IP地址分別按照一定的周期(1秒一次),向組播地址239.0.0.5發送UDP數據報。以便讓在這個組播地址的其它服務節點能夠感知自己的存在

  • 另外,以上UDP數據報文使用的端口是6155。您也可以更改這個端口信息通過類似如下的方式:

#使用組播地址239.0.0.5:19999
multicast://239.0.0.5:19999

 

  •  每個UDP數據報中,包含的主要信息包括本節點ActiveMQ的版本信息,以及連接到自己所需要使用的host名字、協議名和端口信息。類似如下:
default.ActiveMQ-4.ailve%localhost%auto+nio://activemq:61616

 

 2.2.2、transportConnector標簽的關聯設置

任何一個ActiveMQ服務節點A,要連接到另外的ActiveMQ服務節點,都需要使用當前節點A已經公布的transportConnector連接端口,例如以下配置中,能夠供其它服務節點進行連接的就只有兩個transportConnector連接中的任意一個:

......
<transportConnectors>
    <!-- 其它ActiveMQ服務節點,只能使用以下三個連接協議和端口進行連接 -->
    <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
    <transportConnector name="tcp" uri="tcp://0.0.0.0:61614?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    <transportConnector name="nio" uri="nio://0.0.0.0:61618?maximumConnections=1000" />
    <transportConnector name="auto" uri="auto://0.0.0.0:61617?maximumConnections=1000" />   
</transportConnectors>
......

 

 那么要將哪一個連接方式通過UDP數據報向其他ActiveMQ節點進行公布,就需要在transportConnector標簽上使用discoveryUri屬性進行標識,如下所示:

 

......
<transportConnectors>
    ......
    <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    <transportConnector name="auto" uri="auto+nio://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600" discoveryUri="multicast://239.0.0.5" />
</transportConnectors>

......
<networkConnectors>
    <networkConnector uri="multicast://239.0.0.5"/>
</networkConnectors>
......

 

 

2.3、靜態Network Connectors

相比於基於組播發現方式的動態Network Connectors而言,雖然靜態Network Connectors沒有那樣靈活的橫向擴展性,但是卻可以適用於網絡環境受嚴格管理的情況。例如:管理員關閉了交換機/路由器的組播功能、端口受到嚴格管控等等。

配置靜態Network Connectors的ActiveMQ集群的方式也很簡單,只需要更改networkConnectors標簽中的配置即可,而無需關聯改動transportConnectors標簽。但是配置靜態Network Connectors的ActiveMQ集群時,需要注意非常關鍵的細節:每一個節點都要配置其他所有節點的連接位置。

為了演示配置過程,我們假設ActiveMQ集群由兩個節點構成,分別是activemq1:192.168.61.138 和 activemq2:192.168.61.139。那么配置情況如下所示:

  • 192.168.61.138:需要配置activemq2的位置信息以便進行連接:
......
<transportConnectors>
    <transportConnector name="auto" uri="auto+nio://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600&amp;consumer.prefetchSize=5"/>
</transportConnectors>
......

<!-- 請注意,一定需要192.168.61.139(activemq2)提供了這樣的連接協議和端口 -->
<networkConnectors>
    <networkConnector uri="static:(auto+nio://192.168.61.139:61616)"/>
</networkConnectors>
......

 

  • 192.168.61.139:需要配置activemq1的位置信息以便進行連接:
......
<transportConnectors>
    <transportConnector name="auto" uri="auto+nio://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600&amp;consumer.prefetchSize=5"/>
</transportConnectors>

......
<!-- 請注意,一定需要192.168.61.138(activemq1)提供了這樣的連接協議和端口 -->
<networkConnectors>
   <networkConnector uri="static:(auto+nio://192.168.61.138:61616)"/>
</networkConnectors>
......

同理,如果您的ActiveMQ集群規划中有三個ActiveMQ服務節點,那么任何一個節點都應該配置其它兩個服務節點的連接方式。在配置格式中使用“,”符號進行分割:

......
<networkConnectors>
    <networkConnector uri="static:(tcp://host1:61616,tcp://host2:61616,tcp://..)"/>
</networkConnectors>
......

 

 

2.3、其他配置屬性

下表列舉了在networkConnector標簽中還可以使用的屬性以及其意義。請特別注意其中的duplex屬性。如果只從字面意義理解該屬性,則被稱為“雙工模式”;如果該屬性為true,當這個節點使用Network Bridge連接到其它目標節點后,將強制目標也建立Network Bridge進行反向連接。其目的在於讓消息既能發送到目標節點,又可以通過目標節點接受消息,但實際上大多數情況下是沒有必要的,因為目標節點一般都會自行建立連接到本節點。所以,該duplex屬性的默認值為false。

屬性名稱           默認值     屬性意義
name bridge 名稱
dynamicOnly false 如果為true, 持久訂閱被激活時才創建對應的網路持久訂閱。
decreaseNetworkConsumerPriority false 如果為true,網絡的消費者優先級降低為-5。如果為false,則默認跟本地消費者一樣為0.
excludedDestinations empty 不通過網絡轉發的destination
dynamicallyIncludedDestinations empty 通過網絡轉發的destinations,注意空列表代表所有的都轉發。
staticallyIncludedDestinations empty 匹配的都將通過網絡轉發-即使沒有對應的消費者,如果為默認的“empty”,那么說明所有都要被轉發
duplex false 已經進行詳細介紹的“雙工”屬性。
prefetchSize 1000 設置網絡消費者的prefetch size參數。如果設置成0,那么就像之前文章介紹過的那樣:消費者會自己輪詢消息。顯然這是不被允許的。
suppressDuplicateQueueSubscriptions      false 如果為true, 重復的訂閱關系一產生即被阻止(V5.3+ 的版本中可以使用)。
bridgeTempDestinations true 是否廣播advisory messages來創建臨時destination。
alwaysSyncSend false 如果為true,非持久化消息也將使用request/reply方式代替oneway方式發送到遠程broker(V5.6+ 的版本中可以使用)。
staticBridge false 如果為true,只有staticallyIncludedDestinations中配置的destination可以被處理(V5.6+ 的版本中可以使用)。

 

以下這些屬性,只能在靜態Network Connectors模式下使用

屬性名稱     默認值     屬性意義
initialReconnectDelay 1000 重連之前等待的時間(ms) (如果useExponentialBackOff為false)
useExponentialBackOff true 如果該屬性為true,那么在每次重連失敗到下次重連之前,都會增大等待時間
maxReconnectDelay 30000 重連之前等待的最大時間(ms)
backOffMultiplier 2 增大等待時間的系數

 

請注意這些屬性,並不是networkConnector標簽的屬性,而是在uri屬性中進行設置的,例如:

uri="static:(tcp://host1:61616,tcp://host2:61616)?maxReconnectDelay=5000&useExponentialBackOff=false"

 

 三、其他注意事項

  • 關於防火牆:請記得關閉您Linux服務器上對需要公布的IP和端口的限制;

  • 關於hosts路由信息:由於基於組播的動態發現機制,能夠找到的是目標ActiveMQ服務節點的機器名,而不是直接找到的IP。所以請設置當前服務節點的hosts文件,以便當前ActiveMQ節點能夠通過hosts文件中的IP路由關系,得到機器名與IP的映射:

# hosts文件

......
192.168.61.138          activemq1
192.168.61.139          activemq2
......

 

  •  關於哪些協議能夠被用於進行Network Bridges連接:根據筆者以往的使用經驗,只有tcp頭的uri格式(openwire協議)能夠被用於Network Bridges連接;當然您可以使用auto頭,因為其兼容openwire協議;另外,您還可以指定為附加nio頭。

 四、一些博文:

ActiveMQ筆記(3):基於Networks of Brokers的HA方案:http://www.cnblogs.com/leihenqianshang/articles/5623841.html

ActiveMQ筆記(4):搭建Broker集群(cluster):https://www.cnblogs.com/leihenqianshang/articles/5623858.html

ActiveMQ筆記(2):基於ZooKeeper的HA方案:http://www.cnblogs.com/leihenqianshang/articles/5623831.html

架構設計:系統間通信(25)——ActiveMQ集群方案(上):https://blog.csdn.net/yinwenjie/article/details/51124749

架構設計:系統間通信(26)——ActiveMQ集群方案(下):https://blog.csdn.net/yinwenjie/article/details/51205822


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM