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 节点,继续的对外提供服务。

12.ActiveMQ基于 ZooKeeper + LevelDB 的 HA 集群搭建 && 集群Demo_第1张图片

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.201 2181 2888:3888
192.168.204.202 2181 2888:3888
192.168.204.203 2181 2888:3888

      ActiveMQ集群

主机IP 集群通信端口 Web控制台端口 连接Broker节点端口
192.168.204.201 61619 8161 61616
192.168.204.202 61620 8161 61616
192.168.204.203 61621 8161 61616

   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 文件进行配置,配置如下:

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

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


    
    
    
    
        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"
         
        hostname="192.168.204.201"
    />

      6.配置参数介绍:

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

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

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

 12.ActiveMQ基于 ZooKeeper + LevelDB 的 HA 集群搭建 && 集群Demo_第2张图片

     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控制台页面。

12.ActiveMQ基于 ZooKeeper + LevelDB 的 HA 集群搭建 && 集群Demo_第3张图片

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条消息

12.ActiveMQ基于 ZooKeeper + LevelDB 的 HA 集群搭建 && 集群Demo_第4张图片

    ②在 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

你可能感兴趣的:(ActiveMQ,ActiveMQ,+,LevelDB,模式集群)