1. 配置
从 ActiveMQ 5.9 开始, ActiveMQ 的集群实现方式取消了传统的 Master-Slave 方式,增加了基于 ZooKeeper + LevelDB 的 Master-Slave 实现方式。下面将对这种方案进行配置,并进行高可用测试。
1.1 集群部署规划
(1)zookeeper集群环境
可参考 [《zookeeper简介与安装》](http://my.oschina.net/thinwonton/blog/845330) 进行配置
主机 | 端口 |
---|---|
192.168.88.18 | 2181 |
192.168.88.18 | 2182 |
192.168.88.18 | 2183 |
(2)activemq集群环境
主机 | 集群端口 | 管控台端口 | 节点别名 | 节点安装目录 |
---|---|---|---|---|
192.168.88.18 | 61616 | 8161 | node-01 | /usr/local/activemq/node-01 |
192.168.88.18 | 61617 | 8162 | node-02 | /usr/local/activemq/node-02 |
192.168.88.18 | 61618 | 8163 | node-03 | /usr/local/activemq/node-03 |
1.2 配置管控台
修改配置文件 conf/jetty.xml
Node-01 管控台端口
<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"/>
</bean>
Node-02 管控台端口
<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"/>
</bean>
Node-03 管控台端口
<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"/>
</bean>
1.3 配置持久化方式和消息端口
修改conf/activemq.xml配置文件
Node-01
<persistenceAdapter>
<replicatedLevelDB
directory="${activemq.data}/leveldb"
replicas="3"
bind="tcp://0.0.0.0:0"
zkAddress="192.168.88.18:2181,192.168.88.18:2182,192.168.88.18:2183"
zkPath="/activemq/leveldb-stores"
hostname="node-01"
/>
</persistenceAdapter>
<transportConnectors>
<!--修改消息端口-->
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?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
<persistenceAdapter>
<replicatedLevelDB
directory="${activemq.data}/leveldb"
replicas="3"
bind="tcp://0.0.0.0:0"
zkAddress="192.168.88.18:2181,192.168.88.18:2182,192.168.88.18:2183"
zkPath="/activemq/leveldb-stores"
hostname="node-02"
/>
</persistenceAdapter>
<transportConnectors>
<!--修改消息端口-->
<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>
Node-03
<persistenceAdapter>
<replicatedLevelDB
directory="${activemq.data}/leveldb"
replicas="3"
bind="tcp://0.0.0.0:0"
zkAddress="192.168.88.18:2181,192.168.88.18:2182,192.168.88.18:2183"
zkPath="/activemq/leveldb-stores"
hostname="node-03"
/>
</persistenceAdapter>
<transportConnectors>
<!--修改消息端口-->
<transportConnector name="openwire" uri="tcp://0.0.0.0:61618?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>
zkPath:是在zookeeper节点的根路径
hostname:可以理解为别名
注意:hostname 需要查看一下本机的host配置是否有映射,否则在启动集群后,会报UnkownHostName的异常。
补充:需要修改两处host地方
(1)本机的host(词穷了。。。。)
即linux命令行界面中,最前面。。。。唉,看图吧
需要cat 本机的host文件,看是不是映射到本机
(2)刚才activemq.xml配置的hostname
这玩意也要配置到host里面,上面图中配置了,本机IP就是192.168.88.18
1.4 启动
(1)启动zk集群
(2)启动mq集群,记得监听日志,日志文件在node-01/data/activemq.log
验证是否启动成功
(1)使用命令 ps -ef | grep activemq 是否有三个实例
(2)打开管控台 http://192.168.88.18:8161 或者 http://192.168.88.18:8162 或者 http://192.168.88.18:8163,如果集群成功启动,在其中而且仅有一个是可以打开的。
(3)使用zk的工具,查看节点 /activemq/leveldb-stores 中是否有三个子节点,并且是否已经选出master节点。
2. 测试高可用
一个消息发送者和一个消息接收者,消息不断发送和接收,期间,断开activemq的master实例,观察集群是否可以选举出master,然后恢复正常的消息发送接收,观察序号是否连续,最后重启原master,查看zk的节点,它是否已经加入到集群中。
感兴趣的同学可以下载源码,自己测试一下。
代码:https://git.oschina.net/thinwonton/activemq-showcase
实验结果:
activemq的master断开后,消费者和生产者将会出现一瞬间的闪断,即不再进行工作,待集群选举了master后,消费者和生产者将会自动连接到新的mater主机,而且,消息序号仍然连续。