ActiveMQ高可用集群安装、配置、高可用测试html
(ZooKeeper + LevelDB)node
从ActiveMQ 5.9开始,ActiveMQ的集群实现方式取消了传统的Master-Slave方式,增长了基于ZooKeeper + LevelDB的Master-Slave实现方式,其余两种方式目录共享和数据库共享依然存在。mysql
三种集群方式的对比:web
(1)基于共享文件系统(KahaDB,默认):sql
<persistenceAdapter>数据库
<kahaDB directory="${activemq.data}/kahadb"/>apache
</persistenceAdapter>架构
(2)基于JDBC:负载均衡
<bean id="mysql-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">dom
<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
集群原理图:
高可用的原理:使用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表明节点号一、二、3,下同)
五、修改管理控制台端口(默认为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&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>
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&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>
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&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>
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。
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集群的高可用。)
十一、设置开机启动:
# 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上,不能实现消息的高可用。