12.ActiveMQ基于 ZooKeeper + LevelDB 的 HA 集群搭建 && 集群Demo

目录

1.概要

2.ActiveMQ基于 ZooKeeper + levelDB 的  HA 集群搭建

3.ActiveMQ 集群高可用案例


  1.概要

         使用 ZooKeeper 实现的 master-slave 实现方式,是对 ActiveMQ 进行高可用的一种有效的解决方案。即:每一个 节点的 Broker 在 ActiveMQ 启动完成后,会将该节点相关信息注册至 Zookeeper,通过 ZooKeeper 的节点动态感知特性,来实现主从切换、选举等问题。

        在 ZooKeeper + ActiveMQ 集群中,只有其中的一个 Broker 可以对外提供服务(也就是 master 节点),其他的 Broker 节点都处于待机状态(也就是 slave 节点)。如果 master 节点因故障问题而不能对外一共服务时,则利用 ZooKeeper 的内部选举机制,会从 Slave 中选举出一个 Broker 来充当 master 节点,继续的对外提供服务。

2.ActiveMQ基于 ZooKeeper + levelDB 的  HA 集群搭建

       ActiveMQ5.9 以后,推出了基于 ZooKeeper 的 master/slave 主从实现集群。虽然 ActiveMQ 不建议使用 LevelDB 作为存储,主要原因是社区的主要精力都集中在 kahaDB 的维护上,包括 bug 修复等。所以并没有对 LevelDB 做太多的关注,所以它暂时是不作为推荐商用。但实际上在很多公司,仍然采用了 ZooKeeper + LevelDB 方式的高可用集群方案。而实际推荐的方案,仍然是基于KahaDB的文件共享(请移步:ActiveMQ 静态网络连接配置) 以及 JDBC的方式来实现(数据库读写,效率低)。

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓如下是 ActiveMQ 基于 ZooKeeper + levelDB 的  HA 高可用集群的搭建↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

       ActiveMQ 基于 LevelDB 集群搭建官方文档(英文版):ZooKeeper + LevelDB 集群搭建

   2.0 集群方案

       ZooKeeper集群

主机IP消息端口通信端口
192.168.204.20121812888:3888
192.168.204.20221812888:3888
192.168.204.20321812888:3888

      ActiveMQ集群

主机IP集群通信端口Web控制台端口连接Broker节点端口
192.168.204.20161619816161616
192.168.204.20261620816161616
192.168.204.20361621816161616

   2.1 ZooKeeper集群搭建

       基于 ZooKeeper 来搭建 ActiveMQ 集群,前提是需要有一个 ZooKeeper 来进行管理,为了保证 ZooKeeper 的高可用,建议搭建至少3个节点的ZooKeeper集群。如需了解 ZooKeeper 集群的安装,请移步:ZooKeeper集群的安装  (如需了解更多关于ZooKeeper 知识,请移步:ZooKeeper 总结

  2.2 ActiveMQ集群搭建

      1.进入ActiveMQ官网,点击下载:ActiveMQ所有历史版本

      2.本文下载的是最新版本:ActiveMQ-5.15.9

      3.通过 tar zxvf 文件名,将tar.gz包解压缩至指定路径。本文路径:/usr/local/lib/activemq-cluster

      4.进入 activemq-cluster 目录,通过 mv 命令 重命名 为 activemq

         

     5.接下来,便是配置文件的修改。进入 activemq/conf 目录下,分别对集群每个节点 activemq.xml 文件进行配置,配置如下:

           ①在 <persistenceAdapter> 注释掉默认 kahadb 方式存储

           ②添加基于 LevelDB 方式的集群配置,具体配置如下:

<persistenceAdapter>
    <!-- 1.注释掉kahaDB方式存储 -->
    <!-- <kahaDB directory="${activemq.data}/kahadb"/>-->
    <!-- 2.配置基于LevelDB方式存储 + 集群配置 -->
    <replicatedLevelDB
        directory="${activemq.data}/leveldb"
        replicas="3"
        <!-- 不同节点,该端口需修改.192.168.204.202节点,此处端口修改为61620,一次类推,每个节点bind内容必须唯一 -->
        bind="tcp://0.0.0.0:61619"
        zkAddress="192.168.204.201:2181,192.168.204.202:2181,192.168.204.203:2181"
        zkPath="/activemq/leveldb-stores"
         <!-- 不同节点,该IP需修改.192.168.204.202节点,此处IP修改为192.168.204.202一次类推,每个节点bind内容必须唯一 -->
        hostname="192.168.204.201"
    />
</persistenceAdapter>

      6.配置参数介绍:

属性名配置介绍集群每个节点该属性是否必须唯一
directory表示 LevelDB 所在的主工作目录(类似kahaDB)
replicas表示集群总的节点数,用于 master 选举使用。比如我们的集群有 3 个节点,且最多允许一个节点出现故障,那么这个值可以设置为 2,也可以设置为 3 。因为计算公式为(replicas/2)+ 1。如果我们设置为4,就表示不允许 3 个节点的任何一个节点出错。建议选择奇数节点
bind表示当【当前】的节点为 master 时,它会根据绑定好的地址和端口来进行主从复制协议。还支持使用动态端口,只需要使用 tcp://0.0.0.0:0 进行配置;(每个节点端口不能一样)是(不同节点需要修改端口号)
zkAddressZooKeeper的地址。集群模式通过逗号分隔
zkPathActiveMQ 启动时,向 ZooKeeper 中注册的节点路径
hostname本机IP。用于在此节点成为主节点时通告复制服务的主机名。 如果未设置,将自动确定。是(不同节点需要修改为本机IP)

     7.集群之间通信,切记开放指定端口号;亦可关闭防火墙。【生产环境情况下,建议开放端口,不建议关闭防火墙】

       本文集群之间通信,用到 61619 、 61620 、 61621 三个端口,开放这三个端口即可。在 Linux 中如何开放指定端口号,请移步:Linux开放指定端口,如下图所示。8161 和 61616 端口也记得打开,分别是 Web 控制台端口和客户端连接 Broker 端口。

 

     8.至此,ActiveMQ 基于 ZooKeeper + LevelDB 的 HA 集群就搭建完成了

     9.启动集群之前,先启动 ZooKeeper 集群,然后再启动 ActiveMQ 集群。

        如何启动ZooKeeper集群,请移步:ZooKeeper集群的安装 

        启动ActiveMQ集群,分别进入每个节点activemq/bin目录下,通过命令: sh activemq start 启动

     10.启动完成不报错,则说明 ActiveMQ 集群配置成功

       日志路径:activemq/data/activemq.log 。通过 tail 命令查看即可。如果有错误,可以参考 单机版 ActiveMQ 安装 来解决,如有其他问题没有提到,请自行 Baidu or Google。启动成功图示如下(请双击放大,通过Ctrl+鼠标滚轮 缩放查看,因为我是双显示器,哈哈)

        出现如下提示:jolokia-agent: Using policy access restrictor classpath:/jolokia-access.xml | /api | main,则说明当前该节点是 master节点。当前 master 节点 IP 是 192.168.204.201。

     11.此时,你可以通过 http://masterIP:8161 进入web控制台页面查看。其他的 Broker 节点由于都是处于待机状态,所以你是无法进入到 web控制台页面的。只能进入当前 master 的页面。即:ActiveMQ集群正常运行,你只能进入 master 节点的 web控制台页面。

3.ActiveMQ 集群高可用案例

    ActiveMQ 高可用,此处会用到一个 failover 故障转移机制,只需要在 brokerURL中通过如下配置即可:

ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
"failover:(tcp://192.168.204.201:61616,tcp://192.168.204.202:61616,tcp://192.168.204.203:61616)"
);

  Producer端:(消息生产端)

public class Producer {
    public static void main(String[] args) throws InterruptedException {
        //1.创建连接工厂
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("failover:(tcp://192.168.204.201:61616,tcp://192.168.204.202:61616,tcp://192.168.204.203:61616)");
        Connection connection = null;
        Session session = null;
        MessageProducer producer = null;
        try {
            //2.获取连接
            connection = connectionFactory.createConnection();
            //3.启动连接
            connection.start();
            //4.创建会话
            session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
            //5.创建队列对象(目的地)
            Destination destination  = session.createQueue("myQueue");
            //6.创建消息生产者
            producer = session.createProducer(destination);

            for (int i = 0; i < 1000 ; i++) {
                //7.创建消息
                TextMessage message = session.createTextMessage("ActiveMQ:"+i);
                //8.发送消息
                producer.send(message);
            }
        } catch (JMSException e) {
            e.printStackTrace();
        } finally {
            try {
                if(producer != null){
                    producer.close();
                }
                if(connection != null){
                    connection.close();
                }
                if(session != null) {
                    session.close();
                }
            } catch (JMSException e) {
                e.printStackTrace();
            }
        }
    }
}

Consumer端:(消息消费端)

public class Consumer01 {
    public static void main(String[] args) {
        //1.创建连接工厂
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("failover:(tcp://192.168.204.201:61616,tcp://192.168.204.202:61616,tcp://192.168.204.203:61616)");
        Connection connection = null;
        Session session = null;
        try {
            //2.获取连接
            connection = connectionFactory.createConnection();
            //3.启动连接
            connection.start();
            //4.创建会话
            session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
            //5.创建队列对象(目的地)
            Destination destination = session.createQueue("myQueue");
             //6.创建消息消费者
            MessageConsumer consumer = session.createConsumer(destination);
            
            for (int i = 0; i < 10; i++) {
                //7创建消息 & 消费消息
                TextMessage message = (TextMessage)consumer.receive();
                System.out.println(message.getText());
                Thread.sleep(1000);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(connection != null){
                try {
                    connection.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
            if(session != null){
                try {
                    session.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

案例测试:

      ①启动 Producer 端,生产1000条消息。然后在 Consumer 端开始消费。目前连接 master 节点为 192.168.204.201 节点,开始生产1000条消息

    ②在 Consumer 端消费,消费1条休眠1000ms,当消费到几条数据后,我们手工关闭 192.168.204.201 的 master 节点,集群则会通过 ZooKeeper选举机制开始新 master 的选举。然后你会看到 Consumer 端,会通过故障转移机制,重新连接至新的 master 节点,继续消费消息。如下图所示:

        Consumer 端开启消费,连接至 master 192.168.204.201 节点,当消费至 ActiveMQ:6 后,通过2图 kill 命令强制关闭 201 master节点,你会看到 2 图 开始重新选举,然后 192.168.204.202 节点提示:jolokia-agent: Using policy access restrictor classpath:/jolokia-access.xml | /api | main,则说明192.168.204.202 节点被选举为 master节点。然后你再查看 1 图,你发现在报错后,通过故障转移,消费端连接至 192.168.204.202 这个新选举的 master 继续消费。这样便完成了 ActiveMQ + LevelDB的 HA 高可用集群的使用。(2图请双击放大查看)

        当 192.168.204.201 节点重新启动后,会变成 192.168.204.202 的 slave 节点。


        ActiveMQ 基于 ZooKeeper + LevelDB的高可用集群,配置 + 使用,到此结束。写博客好累的说,喜欢的给个赞吧 ^_^

END

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

扛麻袋的少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值