ActiveMQ+ZooKeeper 集群整合

原理简介:
通常在部署ActiveMQ集群的时候,更倾向于使用基于ZooKeeper的Replicated LevelDB Store方式,该方式是Master Slave部署方案的其中一种策略,也是在多台主机实现ActiveMQ集群的主流部署方式。 此教程只保证了高可用性。要想保证负载均衡得再结合Broker Clusters 部署方案,配置网络链接器。html

工做流程:
在ZooKeeper中管理多个Broker节点,根据 Master选举策略让其中一个 Broker选举为Master(只有Master才具有对外提供服务的能力),剩下Broker为slave。
编码时,client端(消费者)经过failover协议来链接ActiveMQ集群。node

1、服务器配置

1. ZooKeeper集群

ZooKeeper集群保证ZooKeeper自己的高可用性。web

1.1 修改ZK配置文件conf/zoo.cfg

主机IP 服务端口(默认) 集群通讯端口 节点目录/opt/下  
192.168.100.142 2181 2888:3888 zookeeper
192.168.100.143 2181 2888:3888 zookeeper
192.168.100.144 2181 2888:3888 zookeeper
集群通讯端口:第一个端口是master和slave之间的通讯端口,默认是2888;第二个端口是leader选举的端口,集群刚启动的时候选举或者leader挂掉以后进行新的选举的端口默认是3888。

在3台主机上都安装zookeeper服务,/opt/zookeeper,并分别配置它们的文件conf/zoo.cfg:apache

  • 主机1(192.168.100.142)
    /opt/zookeeper/conf/zoo.cfg:vim

    # zookeeper的数据存储和日志存储目录(若是目录不存在就新建)
    dataDir=/opt/zookeeper/data
    dataLogDir=/opt/zookeeper/log
    
    # zk集群之间的通讯地址
    server.1=192.168.100.142:2888:3888
    server.2=192.168.100.143:2888:3888
    server.3=192.168.100.144:2888:3888

    建立/opt/zookeeper/data/myid文件,填入数字1:服务器

    # 因为该主机1(192.168.100.142)是server.1,因此在myid中设置数字1
    $ vim /opt/zookeeper/data/myid
  • 主机2(192.168.100.143)
    /opt/zookeeper/conf/zoo.cfg:网络

    dataDir=/opt/zookeeper/data
    dataLogDir=/opt/zookeeper/log
    
    server.1=192.168.100.142:2888:3888
    server.2=192.168.100.143:2888:3888
    server.3=192.168.100.144:2888:3888

    建立/opt/zookeeper/data/myid文件,填入数字2:负载均衡

    # 因为该主机2(192.168.100.143)是server.2,因此在myid中设置数字2
    $ vim /opt/zookeeper/data/myid
  • 主机3(192.168.100.143)
    /opt/zookeeper/conf/zoo.cfg:tcp

    dataDir=/opt/zookeeper/data
    dataLogDir=/opt/zookeeper/log
    
    server.1=192.168.100.142:2888:3888
    server.2=192.168.100.143:2888:3888
    server.3=192.168.100.144:2888:3888

    建立/opt/zookeeper/data/myid文件,填入数字3:编码

    # 因为该主机3(192.168.100.144)是server.3,因此在myid中设置数字3
    $ vim /opt/zookeeper/data/myid

1.2 分别启动zookeeper服务

$ /opt/zookeeper/bin/zkServer.sh start # 启动zk服务
$ /opt/zookeeper/bin/zkServer.sh status # 查看zk服务状态

2. ActiveMQ集群

2.1 修改ActiveMQ配置文件conf/activemq.xmlconf/jetty.xml

主机IP 服务端口(默认) 复制协议端口(动态) jetty控制台端口(默认) 节点目录/opt/下  
192.168.100.142 61616 tcp://0.0.0.0:0 8161 activemq/node1
192.168.100.143 61616 tcp://0.0.0.0:0 8161 activemq/node2
192.168.100.144 61616 tcp://0.0.0.0:0 8161 activemq/node3

在3台主机上都安装activemq 服务,/opt/activemq,并分别配置它们的文件conf/activemq.xml和conf/jetty.xml:

  • 主机1(192.168.100.142)
    /opt/activemq/conf/activemq.xml:

    <!-- 持久化的部分为ZooKeeper集群链接地址-->  
    <persistenceAdapter>  
        <replicatedLevelDB  
          directory="${activemq.data}/leveldb"  
          replicas="3"  
          bind="tcp://0.0.0.0:0"  
          zkAddress="192.168.100.142:2181,192.168.100.143:2181,192.168.100.144:2181"   
          zkPath="/opt/activemq/leveldb-stores"  
          hostname="192.168.100.142"  
          />  
    </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
    -->

    /opt/activemq/conf/jetty.xml:

    <bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
        <property name="host" value="0.0.0.0"/>
        <property name="port" value="8161"/> <!-- 在这里修改端口为8161,默认就是8161 -->
    </bean>
  • 主机2(192.168.100.143)
    /opt/activemq/conf/activemq.xml:

    <persistenceAdapter>  
        <replicatedLevelDB  
          directory="${activemq.data}/leveldb"  
          replicas="3"  
          bind="tcp://0.0.0.0:0"  
          zkAddress="192.168.100.142:2181,192.168.100.143:2181,192.168.100.144:2181"   
          zkPath="/opt/activemq/leveldb-stores"  
          hostname="192.168.100.143"  
          />  
    </persistenceAdapter>

    /opt/activemq/conf/jetty.xml:

    <bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
        <property name="host" value="0.0.0.0"/>
        <property name="port" value="8161"/> <!-- 在这里修改端口为8161,默认就是8161 -->
    </bean>
  • 主机3(192.168.100.144)
    /opt/activemq/conf/activemq.xml:

    <persistenceAdapter>  
        <replicatedLevelDB  
          directory="${activemq.data}/leveldb"  
          replicas="3"  
          bind="tcp://0.0.0.0:0"  
          zkAddress="192.168.100.142:2181,192.168.100.143:2181,192.168.100.144:2181"   
          zkPath="/opt/activemq/leveldb-stores"  
          hostname="192.168.100.144"  
          />  
    </persistenceAdapter>

    /opt/activemq/conf/jetty.xml:

    <bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
        <property name="host" value="0.0.0.0"/>
        <property name="port" value="8161"/> <!-- 在这里修改端口为8161,默认就是8161 -->
    </bean>

2.2 依次启动activemq服务

$ /opt/activemq/bin/activemq start # 启动activemq服务

$ ps -ef|grep activemq # 检查进程是否运行,即activemq是否启动成功
$ netstat -anp|grep 61616 # 查看服务端口61616,监听状况

3、Client使用

该zookeeper+activemq的集群Master Slave部署方案,可以提供(3-1)/2的容错率,即3台服务器容许宕机一台,而不影响整个集群的对外提供服务。

编写代码链接时使用failover策略:

String url = failover:(tcp://192.168.100.142:61616,tcp://192.168.100.143:61616,tcp://192.168.100.144:61616)?initialReconnectDelay=1000