ActiveMQ高可用集群安装、配置、高可用测试 (ZooKeeper + LevelDB)

ActiveMQ高可用集群安装、配置、高可用测试

(ZooKeeper + LevelDB)

 

从ActiveMQ 5.9开始,ActiveMQ的集群实现方式取消了传统的Master-Slave方式,增加了基于ZooKeeper + LevelDB的Master-Slave实现方式,其他两种方式目录共享数据库共享依然存在。

 

三种集群方式的对比:

(1)基于共享文件系统(KahaDB,默认):

<persistenceAdapter>

<kahaDB directory="${activemq.data}/kahadb"/>

</persistenceAdapter>

 

(2)基于JDBC:

<bean id="mysql-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

<property name="driverClassName" value="com.mysql.jdbc.Driver"/>

<property name="url" value="jdbc:mysql://localhost:3306/amq?relaxAutoCommit=true"/>

<property name="username" value="root"/>

<property name="password" value="root"/>

<property name="maxActive" value="20"/> 

<property name="poolPreparedStatements" value="true"/>

</bean>

<persistenceAdapter>

   <jdbcPersistenceAdapter dataDirectory="${activemq.data}" dataSource="#mysql-ds"

         createTablesOnStartup="false"/>

</persistenceAdapter>

 

(3)基于可复制的LevelDB(本教程采用这种集群方式):

LevelDB是Google开发的一套用于持久化数据的高性能类库。LevelDB并不是一种服务,用户需要自行实现Server。是单进程的服务,能够处理十亿级别规模Key-Value型数据,占用内存小。

<persistenceAdapter>

    <replicatedLevelDB

        directory="${activemq.data}/leveldb"

        replicas="3"

        bind="tcp://0.0.0.0:62621"

        zkAddress="localhost:2181,localhost:2182,localhost:2183"

        hostname="localhost"

        zkPath="/activemq/leveldb-stores"

    />

 </persistenceAdapter>

本节课程主要讲解基于ZooKeeper和LevelDB搭建ActiveMQ集群。集群仅提供主备方式的高可用集群功能,避免单点故障,没有负载均衡功能。

官方文档:http://activemq.apache.org/replicated-leveldb-store.html

 

集群原理图:

http://static.oschina.net/uploads/space/2014/0715/153812_6idz_719192.png

 

高可用的原理:使用ZooKeeper(集群)注册所有的ActiveMQ Broker。只有其中的一个Broker可以提供服务,被视为Master,其他的Broker处于待机状态,被视为Slave。如果Master因故障而不能提供服务,ZooKeeper会从Slave中选举出一个Broker充当Master。

     Slave连接Master并同步他们的存储状态,Slave不接受客户端连接。所有的存储操作都将被复制到连接至Master的Slaves。如果Master宕了,得到了最新更新的Slave会成为Master。故障节点在恢复后会重新加入到集群中并连接Master进入Slave模式。

     所有需要同步的disk的消息操作都将等待存储状态被复制到其他法定节点的操作完成才能完成。所以,如果你配置了replicas=3,那么法定大小是(3/2)+1=2。Master将会存储并更新然后等待 (2-1)=1个Slave存储和更新完成,才汇报success。至于为什么是2-1,熟悉Zookeeper的应该知道,有一个node要作为观擦者存在。当一个新的Master被选中,你需要至少保障一个法定node在线以能够找到拥有最新状态的node。这个node可以成为新的Master。因此,推荐运行至少3个replica nodes,以防止一个node失败了,服务中断。(原理与ZooKeeper集群的高可用实现方式类似

1、ActiveMQ集群部署规划:

环境:CentOS 6.6 x64 JDK7

版本:ActiveMQ 5.11.1

ZooKeeper集群环境:192.168.1.81:2181,192.168.1.82:2182,192.168.1.83:2183

     ZooKeeper集群部署请参考《高可用架构篇--第01节--ZooKeeper集群的安装、配置、高可用测试》

主机

集群端口

消息端口

管控台端口

节点安装目录

192.168.1.81

62621

51511

8161

/home/wusc/activemq/node-01

192.168.1.82

62622

51512

8162

/home/wusc/activemq/node-02

192.168.1.83

62623

51513

8163

/home/wusc/activemq/node-03

 

2、防火墙打开对应的端口

 

3、分别在三台主机中创建/home/wusc/activemq目录

$ mkdir /home/wusc/activemq

上传apache-activemq-5.11.1-bin.tar.gz到/home/wusc/activemq目录

 

4、解压并按节点命名

$ cd /home/wusc/activemq

$ tar -xvf apache-activemq-5.11.1-bin.tar.gz

$ mv apache-activemq-5.11.1 node-0X   #(X代表节点号1、2、3,下同)

 

5、修改管理控制台端口(默认为8161)可在conf/jetty.xml中修改,如下:

Node-01管控台端口:

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

Node-02管控台端口:

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

Node-03管控台端口:

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

 

6、集群配置:

     在3个ActiveMQ节点中配置conf/activemq.xml中的持久化适配器。修改其中bind、zkAddress、hostname和zkPath。注意:每个ActiveMQ的BrokerName必须相同,否则不能加入集群。

Node-01中的持久化配置:

<broker xmlns="http://activemq.apache.org/schema/core" brokerName="DubboEdu" dataDirectory="${activemq.data}">

<persistenceAdapter>

<!-- kahaDB directory="${activemq.data}/kahadb"/ -->

<replicatedLevelDB

directory="${activemq.data}/leveldb"

replicas="3"

bind="tcp://0.0.0.0:62621"

zkAddress="192.168.1.81:2181,192.168.1.82:2182,192.168.1.83:2183"

hostname="edu-zk-01"

zkPath="/activemq/leveldb-stores"

/>

</persistenceAdapter>

</broker>

Node-02中的持久化配置:

<broker xmlns="http://activemq.apache.org/schema/core" brokerName="DubboEdu" dataDirectory="${activemq.data}">

<persistenceAdapter>

<!-- kahaDB directory="${activemq.data}/kahadb"/ -->

<replicatedLevelDB

directory="${activemq.data}/leveldb"

replicas="3"

bind="tcp://0.0.0.0:62622"

zkAddress="192.168.1.81:2181,192.168.1.82:2182,192.168.1.83:2183"

hostname="edu-zk-02"

zkPath="/activemq/leveldb-stores"

      />

</persistenceAdapter>

</broker>

Node-03中的持久化配置:

<broker xmlns="http://activemq.apache.org/schema/core" brokerName="DubboEdu" dataDirectory="${activemq.data}">

<persistenceAdapter>

<!-- kahaDB directory="${activemq.data}/kahadb"/ -->

<replicatedLevelDB

directory="${activemq.data}/leveldb"

replicas="3"

bind="tcp://0.0.0.0:62623"

zkAddress="192.168.1.81:2181,192.168.1.82:2182,192.168.1.83:2183"

hostname="edu-zk-03"

zkPath="/activemq/leveldb-stores"

      />

</persistenceAdapter>

</broker>

 

修改各节点的消息端口(注意,避免端口冲突):

Node-01中的消息端口配置:

<transportConnectors>

   <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->

   <transportConnector name="openwire" uri="tcp://0.0.0.0:51511?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>

Node-02中的消息端口配置:

<transportConnectors>

   <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->

   <transportConnector name="openwire" uri="tcp://0.0.0.0:51512?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>

Node-03中的消息端口配置:

<transportConnectors>

   <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->

   <transportConnector name="openwire" uri="tcp://0.0.0.0:51513?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>

 

7、按顺序启动3个ActiveMQ节点:

$ /home/wusc/activemq/node-01/bin/activemq start

$ /home/wusc/activemq/node-02/bin/activemq start

$ /home/wusc/activemq/node-03/bin/activemq start

监听日志:

$ tail -f /home/wusc/activemq/node-01/data/activemq.log

$ tail -f /home/wusc/activemq/node-02/data/activemq.log

$ tail -f /home/wusc/activemq/node-03/data/activemq.log

 

8、集群的节点状态分析:

集群启动后对ZooKeeper数据的抓图,可以看到ActiveMQ的有3个节点,分别是00000000000,00000000001,00000000002。

以下第一张图展现了00000000000的值,可以看到elected的值是不为空,说明这个节点是Master,其他两个节点是Slave。

918a0b4df89e3a8891d040e01aa4238f7e6.jpg

446ae99a65a2f9e6a5e4921ad747ed32942.jpg

1ac1dae1f7e70615faf3d4fc3a71a6e9cbb.jpg

 

 

9、集群可用性测试(配置和测试代码,请看视频):

ActiveMQ的客户端只能访问Master的Broker,其他处于Slave的Broker不能访问。所以客户端连接Broker应该使用failover协议。

failover:(tcp://192.168.1.81:51511,tcp://192.168.1.82:51512,tcp://192.168.1.83:51513)?randomize=false

 

10、集群高可用测试(请看视频)

    当一个ActiveMQ节点挂掉,或者一个ZooKeeper节点挂掉,ActiveMQ服务依然正常运转。如果仅剩一个ActiveMQ节点,因为不能选举Master,ActiveMQ不能正常运转;同样的,如果ZooKeeper仅剩一个节点活动,不管ActiveMQ各节点是否存活,ActiveMQ也不能正常提供服务

ActiveMQ集群的高可用,依赖于ZooKeeper集群的高可用。

 

11、设置开机启动:

# vi /etc/rc.local

su - wusc -c '/home/wusc/activemq/node-01/bin/activemq start'

su - wusc -c '/home/wusc/activemq/node-02/bin/activemq start'

su - wusc -c '/home/wusc/activemq/node-03/bin/activemq start'

 

12、配置优化(可选)

updateURIsURL,通过URL(或者本地路径)获取重连的url,这样做具有良好的扩展性,因为客户端每次连接都是从URL(或文件)中加载一次,所以可以随时从文件中更新url列表,做到动态添加MQ的备点。

failover:()?randomize=false&updateURIsURL=file:/home/wusc/activemq/urllist.txt

urllist.txt中的地址通过英文逗号分隔,示例:

tcp://192.168.1.81:51511,tcp://192.168.1.82:51512,tcp://192.168.1.83:51513

 

最后,附上官方文档的一则警告,请使用者注意。replicatedLevelDB不支持延迟或者计划任务消息。这些消息存储在另外的LevelDB文件中,如果使用延迟或者计划任务消息,将不会复制到slave Broker上,不能实现消息的高可用。

转载于:https://my.oschina.net/u/3155476/blog/3068782

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值