ActiveMQ 高可用集群(基于ZooKeeper + LevelDB)

activemq+Zookeper高可用集群方案配置

在高并发、对稳定性要求极高的系统中,高可用的是必不可少的,。从ActiveMQ 5.9开始,ActiveMQ的集群实现方式取消了传统的Master-Slave方式,增加了基于ZooKeeper + LevelDB 的 Master-Slave 实现方式。

ActiveMQ的高可用原理

  1. 使用ZooKeeper(集群)注册所有的ActiveMQ Broker。只有其中的一个Broker可以提供服务,被视为 Master,其他的 Broker 处于待机状态,被视为Slave。如果Master因故障而不能提供服务,Zookeeper会从Slave中选举出一个Broker充当Master。
  2. Slave连接Master并同步他们的存储状态,Slave不接受客户端连接。所有的存储操作都将被复制到 连接至 Master的Slaves。如果Master宕了,得到了最新更新的Slave会成为 Master。故障节点在恢复后会重新加入到集群中并连接Master进入Slave模式。(Redis Sentinel主从高可用的方式很像,这里的zookeeper起到的作用和reids里的sentinel作用差不多)
  3. 另外,附上官方文档的一则警告,请使用者注意。replicated LevelDB 不支持延迟或者计划任务消息。这 些消息存储在另外的LevelDB文件中,如果使用延迟或者计划任务消息,将不会复制到Slave Broker上,不能实现消息的高可用。

ActiveMQ集群配置

环境准备

  1. 准备zookeeper 集群 3台
  2. 在在3台服务器安装好 ActiveMQ

修改配置:修改每一台 acrivemq 的 activemq.xml 文件的<persistenceAdapter>标签

机器1:

<persistenceAdapter>
  <replicatedLevelDB
    directory="${activemq.data}/leveldb" #数据存储路径
    replicas="3" #节点个数
    bind="tcp://0.0.0.0:0" #用于各个节点之间的通讯
    zkAddress="192.168.72.129:2181,192.168.72.130:2181,192.168.72.131:2181"
    hostname="192.168.72.129"
    zkPath="/activemq/leveldb-stores"/>#在zookeeper中集群相关数据存放路径
</persistenceAdapter>
<!-- 
# directory: 存储数据的路径
# replicas:集群中的节点数【(replicas/2)+1公式表示集群中至少要正常运行的服务数量】,3台集群那么允许1台宕机, 另外两台要正常运行  
# bind:当该节点成为master后,它将绑定已配置的地址和端口来为复制协议提供服务。还支持使用动态端口。只需使用tcp://0.0.0.0:0进行配置即可,默认端口为61616。 
# zkAddress:ZK的ip和port, 如果是集群,则用逗号隔开(这里作为简单示例ZooKeeper配置为单点, 这样已经适用于大多数环境了, 集群也就多几个配置) 
# zkPassword:当连接到ZooKeeper服务器时用的密码,没有密码则不配置。 
# zkPah:ZK选举信息交换的存贮路径,启动服务后actimvemq会到zookeeper上注册生成此路径   
# hostname: ActiveMQ所在主机的IP
# 更多参考:http://activemq.apache.org/replicated-leveldb-store.html
-->

机器2:

<persistenceAdapter>
  <replicatedLevelDB
    directory="${activemq.data}/leveldb" #数据存储路径
    replicas="3" #节点个数
    bind="tcp://0.0.0.0:0" #用于各个节点之间的通讯
    zkAddress="192.168.72.129:2181,192.168.72.130:2181,192.168.72.131:2181"
    hostname="192.168.72.130"
    zkPath="/activemq/leveldb-stores"/>#在zookeeper中集群相关数据存放路径
</persistenceAdapter>
<!-- 
# directory: 存储数据的路径
# replicas:集群中的节点数【(replicas/2)+1公式表示集群中至少要正常运行的服务数量】,3台集群那么允许1台宕机, 另外两台要正常运行  
# bind:当该节点成为master后,它将绑定已配置的地址和端口来为复制协议提供服务。还支持使用动态端口。只需使用tcp://0.0.0.0:0进行配置即可,默认端口为61616。 
# zkAddress:ZK的ip和port, 如果是集群,则用逗号隔开(这里作为简单示例ZooKeeper配置为单点, 这样已经适用于大多数环境了, 集群也就多几个配置) 
# zkPassword:当连接到ZooKeeper服务器时用的密码,没有密码则不配置。 
# zkPah:ZK选举信息交换的存贮路径,启动服务后actimvemq会到zookeeper上注册生成此路径   
# hostname: ActiveMQ所在主机的IP
# 更多参考:http://activemq.apache.org/replicated-leveldb-store.html
-->

机器3:


<persistenceAdapter>
  <replicatedLevelDB
    directory="${activemq.data}/leveldb" 
    replicas="3"
    bind="tcp://0.0.0.0:0"
    zkAddress="192.168.72.129:2181,192.168.72.130:2181,192.168.72.131:2181"
    hostname="192.168.72.131"
    zkPath="/activemq/leveldb-stores"/>
</persistenceAdapter>
<!-- 
# directory: 存储数据的路径
# replicas:集群中的节点数【(replicas/2)+1公式表示集群中至少要正常运行的服务数量】,3台集群那么允许1台宕机, 另外两台要正常运行  
# bind:当该节点成为master后,它将绑定已配置的地址和端口来为复制协议提供服务。还支持使用动态端口。只需使用tcp://0.0.0.0:0进行配置即可,默认端口为61616。 
# zkAddress:ZK的ip和port, 如果是集群,则用逗号隔开(这里作为简单示例ZooKeeper配置为单点, 这样已经适用于大多数环境了, 集群也就多几个配置) 
# zkPassword:当连接到ZooKeeper服务器时用的密码,没有密码则不配置。 
# zkPah:ZK选举信息交换的存贮路径,启动服务后actimvemq会到zookeeper上注册生成此路径   
# hostname: ActiveMQ所在主机的IP
# 更多参考:http://activemq.apache.org/replicated-leveldb-store.html
-->

启动测试

  1. 启动zookeeper 集群

  2. 在安装目录下的bin目录,分别启动每台activemq

    ./activemq start

  3. 查看zookeeper 集群下的节点情况
    在zookeeper的bin目录下使用./zkCli.sh 连接zookeeper。
    使用命令 :ls /activemq/leveldb-stores 查看节点情况:
    在这里插入图片描述
    命令:get /activemq/leveldb-stores/XXXXXXXXX 查看具体情况,
    在这里插入图片描述

  4. 使用java代码连接activemq集群,并进行宕机验证(故障迁移验证)。
    客户端:

    public class ActivemqProducer {
        static String BROCKER_URL = "failover:(tcp://192.168.72.129:61616,tcp://192.168.72.130:61616,tcp://192.168.72.131:61616)";
        static String QUEUE_NAME = "cluster-queue";
    
        public static void main(String[] args) throws JMSException {
            // 1. 创建连接工厂
            ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(BROCKER_URL);
            // 2. 获取连接 并启动
            Connection connection = activeMQConnectionFactory.createConnection();
            connection.start();
            // 3. 创建session 并开启事务,参数一:事务,参数二:签收
            Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
            //4. 创建目的地,队列
            Queue queue = session.createQueue(QUEUE_NAME);
            // 5.创建消息生产者
            MessageProducer messageProducer = session.createProducer(queue);
    
            try {
                // 6.通过 messageProducer 发送3条消息
                for (int i = 1; i <= 3; i++) {
                    TextMessage textMessage = session.createTextMessage("消息 ->" + i);
                    messageProducer.send(textMessage);
                }
                // 提交事务
                session.commit();
            } catch (JMSException e) {
                // 回滚
                session.rollback();
                e.printStackTrace();
            }
    
            System.out.println("发送消息完成......");
            // 7.关闭资源
            messageProducer.close();
            session.close();
            connection.close();
        }
    }
    

    运行代码:此时消息能够正常发送。也能正常接收,

    我们故意停掉 129 机器,在此进行验证,
    在这里插入图片描述
    运行代码,依然可以正常的发送和接收消息。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值