先来考虑这样一个问题:引入ActiveMQ之后如何保证其高可用性呢?没错,我们之前讲到过的持久化、事务和签收都是保证可靠性的机制,在实际运用中,消息队列必然和分布式是分不开的,所以我们必须知道ActiveMQ的集群配置。ActiveMQ官网也说了,以后的版本可能会使用基于LevelDB集群的方式,所以我们来说说基于Zookeeper和LevelDB的集群化配置吧。
一、集群的方式
集群方式有三种,分别是:
1、基于sharedFileSystem共享文件系统
2、基于JDBC
3、基于可复制的LevelDB
官网上的描述:
5.6版本以后推出了LevelDB的持久化引擎,它使用了自定义的索引代替常用的BTree索引,其持久化性能高于KahaDB,虽然默认的持久化方式还是kahaDB,但是LevelDB可能会是趋势。在5.9版本中还提供了基于LevelDB和zookeeper的数据复制方式,作为Master-Slave方式的首选数据复制方案。
二、关于zk+Replicated LevelDB Store
本次案例使用zk+Replicated LevelDB Store的方式。
1、是什么?
从5.9版本开始,ActiveMQ的集群实现方式取消了传统的Master-Slave方式,增加了基于zookeeper+LevelDB的Master-Slave方式,从5.9版本以后也是官网的推荐。
基于zookeeper和LevelDB搭建ActiveMQ集群。集群仅提供主备方式的高可用集群功能,避免单点故障。
2、官网集群原理图
原理解释:
使用zookeeper集群注册所有的ActiveMQ Broker,但只有其中的一个Broker可以提供服务它将被视为Master,其他的Broker被视为slave。
如果Master因故障而不能提供服务,zookeeper会从slave中选举出一个Broker充当Master。slave连接master并同步他们的存储状态,slave不接受客户端连接,所有的存储操作都将被复制到连接至master的slave。如果master宕机得到了最新更新的salve会成为master。故障节点在恢复后会重新加入到集群中并连接master进入slave模式。
所有需要同步消息的操作都将等待存储状态被复制到其他法定节点的操作完成才能完成。所以,如果你配置了replicate=3,那么法定大小为(3/2)+1=2。master将会存储并更新然后等待(2-1)=1个slave存储和更新完成才汇报success。
三、zk+Replicated LevelDB Store的部署规划和步骤
1、环境和版本
CentOs 6.8 + Jdk 1.8.0_201 + zookeeper-3.4.9 + apache-activemq-5.15.9
2、关闭防火墙
[root@localhost bin]# firewall-cmd --state
running
[root@localhost bin]# systemctl stop firewalld.service
[root@localhost bin]# systemctl disable firewalld.service
3、要求具备zk集群并可以成功启动
4、集群部署规划列表
主机 | zk集群端口 | AMQ消息bind端口 | AMQ消息TCP端口 | 管理控制台端口 | AMQ节点安装目录 |
---|---|---|---|---|---|
192.168.179.127 | 2181 | binf="tcp://0.0.0.0:63631" | 61616 | 8161 | /mq_cluster/mq_node01 |
192.168.179.128 | 2181 | binf="tcp://0.0.0.0:63632" | 61617 | 8162 | /mq_cluster/mq_node02 |
192.168.179.129 | 2181 | binf="tcp://0.0.0.0:63633" | 61618 | 8163 | /mq_cluster/mq_node03 |
5、创建三台集群目录
下面的操作是在一台服务器上操作的。如果是三个不同的服务器,则需要各自建立自己的mq安装目录。
[root@localhost bin]# mkdir /mq_cluster
[root@localhost bin]# cd /mq_cluster/
[root@localhost mq_cluster]# cp -r /home/shengyu/software/activemq/ mq_node01
[root@localhost mq_node01]# cp -r /home/shengyu/software/activemq/ mq_node02
[root@localhost mq_node01]# cp -r /home/shengyu/software/activemq/ mq_node03
[root@localhost mq_cluster]# ll
total 0
drwxr-xr-x 11 root root 204 Aug 7 04:36 mq_node01
drwxr-xr-x 11 root root 204 Aug 7 04:33 mq_node02
drwxr-xr-x 11 root root 204 Aug 7 04:33 mq_node03
6、修改管理控制台端口
a.mq_node01全部默认不动
b.mq_node02和mq_node03修改对应端口
修改jetty.xml
7、hostname名字映射
[root@localhost conf]# vim /etc/hosts
8、ActiveMQ集群配置
a.01/02/03路径
修改的文件都是各自目录的activemq.xml
b.3个节点的BrokerName要求全部一致
c.3个节点的持久化配置
<persistenceAdapter>
<replicatedLevelDB
directory="${activemq-data}/leveldb"
replicas="3"
bind="tcp://0.0.0.0:0:63631"
zkAddress="192.168.179.127:2191,192.168.179.128:2192,192.168.179.129:2193"
zkPassword="admin"
zkPath="/activemq/leveldb-stores"
hostname="myBroker-server"
/>
</persistenceAdapter>
9、修改各节点的消息端口
a.mq_node01全部默认不动
b.mq_node01和mq_node02
10、按顺序启动3个ActiveMQ节点,前提是zk集群已经启动
可以写个脚本启动,内容如下:
zk_batch.sh
#!/bin/sh
cd /myZookeeper/zk01/bin
./zkServer.sh start
cd /myZookeeper/zk02/bin
./zkServer.sh start
cd /myZookeeper/zk02/bin
./zkServer.sh start
amq_batch.sh
#!/bin/sh
cd /my_cluster/mq_node01/bin
./activemq start
cd /my_cluster/mq_node02/bin
./activemq start
cd /my_cluster/mq_node03/bin
./activemq start
11、zk集群的节点状态说明
1>3台zk集群任意连接一台
[root@master ~]# cd /opt/software/zookeeper-3.4.14/bin/
[root@master bin]# ./zkCli.sh
2>查看master
[zk: localhost:2181(CONNECTED) 0] ls /
[activemq, zookeeper]
集群启动后对zookeeper数据的抓图,可以看到ActiveMQ有三个节点,分别是00000000000,00000000001,00000000002
上图第一个红框处00000000000的值可以看到elected的值不为空,说明这个节点是Master,其他两个节点为Slave
四、集群可用性测试
ActiveMQ的客户端只能访问master的Broker,其他处于Slave的Broker不能访问,所以客户端连接的Broker应该使用failover协议(失败转移)。
当一个MQ节点挂掉或者一个zookeeper节点挂掉,MQ服务依然正常运转,如果仅剩一个MQ节点,由于不能选举master,所以MQ不能正常运行。
同样的,如果zookeeper仅剩一个节点活动,不管MQ各节点存活,MQ也不能正常提供服务。(ActiveMQ集群的高可用,依赖于zookeeper集群的高可用)
a.干掉一个ActiveMQ节点,他会自动切换到另一个ActiveMQ节点
b.代码(生产者和消费者都修改)
public static final String ACTIVEMQ_URL="failover:(tcp://192.168.179.128:61616,tcp://192.168.179.128:61617,tcp://192.168.179.128:61618)";
