从 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:0" zkAddress="127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183" zkSessionTimeout="2s" hostname="lmg-zk-01" 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 集群的高可用实现方式类似)
一、activemq集群配置
前提:环境的搭建,均一台机器上
准备好3份activemq可执行的文件,
1)分别修改conf/activemq.xml,conf/jetty.xml文件如下:
<persistenceAdapter> <replicatedLevelDB directory="${activemq.data}/leveldb" replicas="3" bind="tcp://0.0.0.0:0" zkAddress="127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183" zkSessionTimeout="2s" hostname="lmg-zk-01" zkPath="/activemq/leveldb-stores"/> </persistenceAdapter>为了避免冲突,确保端口和连接地址不一致,如下设置:
uri | port | |
activemq-1 | tcp://0.0.0.0:51616 | 8161 |
activemq-2 | tcp://0.0.0.0:51626 | 8162 |
activemq-3 | tcp://0.0.0.0:51636 | 8163 |
注意:3个activemq节点中的`brokerName`必须相同,否则不能加入集群
二、zookeeper集群的搭建
可参考:http://www.cnblogs.com/yjmyzz/p/4587663.html
三、校验
1)启动zk1,zk2,zk3,以及activemq-1,activemq-2,activemq3
2)验证
为了验证是否高可用,我们采用Zooinspector对集群节点状态进行监控,Zooinspector的安装见:https://github.com/liaomengge/zooinspector
分别开启3个Zooinspector进行监控,其一图如下:
00000000004这个节点中的`elected`不为null,说明此节点为Master节点,然后,手动kill掉该Master节点,观察Zooinspector的节点状态,如下:
00000000004被kill之后,00000000005提升为Master节点,继续运行,即搭建成功。
参考文章:
http://activemq.apache.org/replicated-leveldb-store.html