基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

一. zookeeper安装(集群):

Dubbo 建议使用Zookeeper 作为服务的注册中心。
Zookeeper 集群中只要有过半的节点是正常的情况下,那么整个集群对外就是可用的。正是基于这个
特性,要将ZK 集群的节点数量要为奇数(2n+1:如3、5、7 个节点)较为合适。

 

zookeeper 集群机器规划:

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

服务器 1:10.0.70.12 端口 :2181、2881、3881

服务器 2:10.0.70.13 端口 :2182、2882、3882

服务器 3:10.0.70.14 端口 :2183、2883、3883

 

1. 下载或上传 zookeeper-3.4.6到/home/fajun/zookeeper/目录 :

$ cd /home/fajun/zookeeper/

$ wget http://apache.fayea.com/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz

 2. 解压 zookeepe安装包 ,并按节点号对 zookeeper目录 重命名:

$ tar -zxvf zookeeper-3.4.6.tar.gz

服务器1:

$ mv zookeeper-3.4.6 node-01

服务器2:

$ mv zookeeper-3.4.6 node-02

服务器3:

$ mv zookeeper-3.4.6 node-03

3. 在各zookeeper节点目录下创建:

$ cd /home/fajun/zookeeper/node-0X (X代表节点号 1、2、3,以下同解 )

$ mkdir data

$ mkdir logs

4. 将 zookeeper/node-0X/conf/目录下的 zoo_sample.cfg文件拷贝一份,命名为zoo.cfg:

$ cp zoo_sample.cfg zoo.cfg

5. 修改 zoo.cfg配置文件 :

(1) zookeeper/node-01的配置(/home/fajun/zookeeper/node-01/conf/zoo.cfg)如下:

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

tickTime=2000

initLimit=10

syncLimit=5

dataDir=/home/fajun/zookeeper/node-01/data

dataLogDir=/home/fajun/zookeeper/node-01/logs

clientPort=2181

server.1=10.0.70.12:2881:3881

server.2=10.0.70.13:2882:3882

server.3=10.0.70.14:2883:3883

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

 (2) zookeeper/node-02的配置(/home/fajun/zookeeper/node-02/conf/zoo.cfg)如下:

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

tickTime=2000

initLimit=10

syncLimit=5

dataDir=/home/fajun/zookeeper/node-02/data

dataLogDir=/home/fajun/zookeeper/node-02/logs

clientPort=2182

server.1=10.0.70.12:2881:3881

server.2=10.0.70.13:2882:3882

server.3=10.0.70.14:2883:3883

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

(3) zookeeper/node-03的配置(/home/fajun/zookeeper/node-03/conf/zoo.cfg)如下:

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

tickTime=2000

initLimit=10

syncLimit=5

dataDir=/home/fajun/zookeeper/node-03/data

dataLogDir=/home/fajun/zookeeper/node-03/logs

clientPort=2183

server.1=10.0.70.12:2881:3881

server.2=10.0.70.13:2882:3882

server.3=10.0.70.14:2883:3883

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

参数说明 参数说明 :
tickTime=2000

这个时间是作为Zookeeper服务器之间或客户端与服务器之间维持心跳的时隔 ,也就是每 个 tickTime时间就会发送一个心跳

initLimit=10

这个配置项是用来配置Zookeeper接受客户端(这里所说的客户端不是用户连接Zookeeper服务器的客户端,而是Zookeeper服务器集群中连接到Leader的Follower服务器)初始化连接时最长能忍受多少个心跳时间间隔数。当已经超过10个心跳的时间(也就是tickTime)长度后Zookeeper服务器还没有收到客户端的返回信息,那么表明这个客户端连接失败。总的时间长度就是10*2000=20秒

syncLimit=5

syncLimit这个配置项标识Leader与Follower之间发送消息,请求和应答时间长度,最长不能超过多少个tickTime的时间长度,总的时间长度就是5*2000=10秒。

dataDir=/home/fajun/zookeeper/node-01/data

dataDir顾名思义就是Zookeeper保存数据的目录,默认情况下Zookeeper将写数据的日志文件也保存在这个目录里。

clientPort=2181

clientPort这个端口就是客户端(应用程序)连接Zookeeper服务器的端口,Zookeeper会监听这个端口接受客户端的访问请求。

 

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

server.A=B:C:D

server.1=10.0.70.12:2881:3881

server.2=10.0.70.13:2882:3882

server.3=10.0.70.14:2883:3883

A是一个数字,表示这个是第几号服务器;

B是这个服务器的IP地址(或者是与IP地址做了映射的主机名);

C第一个端口用来集群成员的信息交换,表示这个服务器与集群中的Leader服务器交换信息的端口;

D是在leader挂掉时专门用来进行选举leader所用的端口。

注意:如果是伪集群的配置方式,不同的Zookeeper实例通信端口号不能一样,所以要给它们分配不同的端口号。

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

6. 在dataDir=/home/fajun/zookeeper/node-0X/data下创建myid文件并在对应的IP的机器上输入对应的编号:

如在node-01上,myid文件内容就是1,node-02上就是2,node-03上就是3:

$  vi /home/fajun/zookeeper/node-01/data/myid  ##值为1
$  vi /home/fajun/zookeeper/node-02/data/myid  ##值为2
$  vi /home/fajun/zookeeper/node-03/data/myid  ##值为3

 7. 在防火墙中打开要用到的端口218X、288X、388X切换到root用户权限,执行以下命令:

# chkconfig iptables on
# service iptables start
# vi /etc/sysconfig/iptables

如服务器01增加以下3行:

## zookeeper

-A INPUT -m state --state NEW -m tcp -p tcp --dport 2181 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 2881 -j ACCEPT
-A INPUT -m state- -state NEW -m tcp -p tcp --dport 3881 -j ACCEPT

8. 重启防火墙:

#service iptables restart
查看防火墙端口状态:
#service iptables status

9. 启动并测试(要用fajun用户启动,不要用root):

(1) 使用fajun用户到/home/fajun/zookeeper/node-0X/bin目录中分别执行:

$ /home/fajun/zookeeper/node-01/bin/zkServer.sh start
$ /home/fajun/zookeeper/node-02/bin/zkServer.sh start
$ /home/fajun/zookeeper/node-03/bin/zkServer.sh start

(2) 输入jps命令查看进程

其中,QuorumPeerMain是zookeeper进程,说明启动正常

$ jps
1456
QuorumPeerMain

(3) 查看状态(leader的为主节点,follower为从节点):

$  /home/fajun/zookeeper/node-0X/bin/zkServer.sh status
JMX enabled by default
Using config: /home/fajun/zookeeper/node-0X/bin/../conf/zoo.cfg
Mode: (leader/follower)

(4) 查看zookeeper服务输出信息,由于服务信息输出文件在/home/fajun/zookeeper/node-0X/bin/zookeeper.out

$ tail -500f zookeeper.out

10. 停止zookeeper进程:

$ ./zkServer.sh stop

11. 配置zookeeper开机使用fajun用户启动:

编辑node-01、node-02、node-03服务器中的/etc/rc.local文件,分别加入:

su - fajun -c  '/home/fajun/zookeeper/node-01/bin/zkServer.sh start'
su - fajun -c  '/home/fajun/zookeeper/node-02/bin/zkServer.sh start'
su - fajun -c  '/home/fajun/zookeeper/node-03/bin/zkServer.sh start'

二. ActiveMq配置:

1. ActiveMq集群部署规划:

  环境:Centos6.6、JDK1.7

  版本:ActiveMq 5.11.1

  zookeeper集群环境:10.0.70.12:2181、10.0.70.13:2182、10.0.70.14:2183

主机 集群端口 消息端口 管控台端口 ActiveMq节点安装目录
10.0.70.12 62621 51511 8161 /home/fajun/activemq/node-01
10.0.70.13 62622 51512 8162 /home/fajun/activemq/node-02
10.0.70.14 62623 51513 8163 /home/fajun/activemq/node-03

 

 

 

 

 

2. 防火墙开放对应上表格管控台端口

3. 分别在三台主机上创建/home/fajun/activemq目录

$ mkdir /home/fajun/activemq

4. 上传apache-activemq-5.11.1-bin.tar.gz到三台主机的/home/fajun/activemq目录下

$ cd /home/fajun/activemq

$ tar -zxvf apache-activemq-5.11.1-bin.tar.gz

$ mv apache-activemq-5.11.1 node-0X(X代表节点0、1、2,下同)

5. 修改三台主机管控台端口(/home/fajun/activemq/node-0X/conf/jetty.xml),默认端口8161:

node-01管控台端口:

<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
      <!-- the default port number for the web console -->
      <property name="host" value="0.0.0.0"/>
      <property name="port" value="8161"/>
</bean>

node-02管控台端口:

<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
      <!-- the default port number for the web console -->
      <property name="host" value="0.0.0.0"/>
      <property name="port" value="8162"/>
</bean>

 node-03管控台端口:

<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
      <!-- the default port number for the web console -->
      <property name="host" value="0.0.0.0"/>
      <property name="port" value="8163"/>
</bean>

 6. 集群配置:

在3个ActiveMQ节点中配置conf/activemq.xml中的持久化适配器。

修改其中bind、zkAddress、hostname和zkPath。

注意:每个ActiveMQ的brokerName必须相同,否则不能加入集群。

node-01中的持久化配置:

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

<broker xmlns="http://activemq.apache.org/schema/core" brokerName="MandaoDubbo" dataDirectory="${activemq.data}">
    <!--kahaDB directory="${activemq.data}/kahadb"/ -->
  <persistenceAdapter>
      <replicatedLevelDB directory="${activemq.data}/leveldb" 
          replicas="3"
          bind="tcp://0.0.0.0:62621"
          zkAddress="10.0.70.12:2181,10.0.70.13:2182,10.0.70.14:2183"
          hostname="10.0.70.12"
          zkPath="/activemq/leveldb-stores"
      />
  </persistenceAdapter>
</broker>

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

node-02中的持久化配置:

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

<broker xmlns="http://activemq.apache.org/schema/core" brokerName="MandaoDubbo" dataDirectory="${activemq.data}">
    <!--kahaDB directory="${activemq.data}/kahadb"/ -->
  <persistenceAdapter>
      <replicatedLevelDB directory="${activemq.data}/leveldb" 
          replicas="3"
          bind="tcp://0.0.0.0:62622"
          zkAddress="10.0.70.12:2181,10.0.70.13:2182,10.0.70.14:2183"
          hostname="10.0.70.13"
          zkPath="/activemq/leveldb-stores"
      />
  </persistenceAdapter>
</broker>

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

 node-03中的持久化配置:

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

<broker xmlns="http://activemq.apache.org/schema/core" brokerName="MandaoDubbo" dataDirectory="${activemq.data}">
    <!--kahaDB directory="${activemq.data}/kahadb"/ -->
  <persistenceAdapter>
      <replicatedLevelDB directory="${activemq.data}/leveldb" 
          replicas="3"
          bind="tcp://0.0.0.0:62623"
          zkAddress="10.0.70.12:2181,10.0.70.13:2182,10.0.70.14:2183"
          hostname="10.0.70.14"
          zkPath="/activemq/leveldb-stores"
      />
  </persistenceAdapter>
</broker>

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

7. 修改各节点的消息端口(注意,避免端口冲突),默认消息端口61616:

node-01中的消息端口配置:

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

<transportConnectors>
    <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
    <transportConnector name="openwire" uri="tcp://0.0.0.0:51511?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
</transportConnectors>

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

node-02中的消息端口配置:

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

<transportConnectors>
    <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
    <transportConnector name="openwire" uri="tcp://0.0.0.0:51512?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
</transportConnectors>

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

 node-03中的消息端口配置:

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

<transportConnectors>
    <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
    <transportConnector name="openwire" uri="tcp://0.0.0.0:51513?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
</transportConnectors>

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

8.设置开机启动:

# vi /etc/rc.local
su - fajun -c '/home/fajun/activemq/node-01/bin/activemq start'
su - fajun -c '/home/fajun/activemq/node-02/bin/activemq start'
su - fajun -c '/home/fajun/activemq/node-03/bin/activemq start'

9. 按顺序启动3个ActiveMq节点:

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

$ /home/fajun/activemq/node-01/bin/activemq start
$ /home/fajun/activemq/node-02/bin/activemq start
$ /home/fajun/activemq/node-03/bin/activemq start
监听日志:
$ tail -f /home/fajun/activemq/node-01/data/activemq.log
$ tail -f /home/fajun/activemq/node-02/data/activemq.log
$ tail -f /home/fajun/activemq/node-03/data/activemq.log

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

10.集群的节点状态分析:

集群启动后对ZooKeeper数据的抓图,可以看到ActiveMQ的有3个节点,分别是000000000004,00000000003,00000000002。

以下第一张图展现了00000000002的值,可以看到elected的值是不为空,说明这个节点是Master,其他两个节点是Slave。

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

11. 集群可用性测试:

ActiveMQ的客户端只能访问Master的Broker,其他处于Slave的Broker不能访问。

所以客户端连接Broker应该使用failover协议:

failover:(tcp://10.0.70.12:51511,tcp://10.0.70.13:51512,tcp://10.0.70.14:51513)?randomize=false

Ps : ActiveMq(下面简称Mq节点)分为Master[主]、Slave[从]

模拟场景1

当前环境:10.0.70.12、10.0.70.13、10.0.70.14 上的Mq节点都是正常运行的(下面简称12、13、14),12是Master  

模拟线上环境异常:停掉12上的Mq节点

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

日志分析:12的Mq尝试重连,发现连不上,接着重连上了13上的Mq节点(说明13推举成了Master)继续消费,消息并没有中断,309是12还没宕掉时消费的的日志,310是新的Master(13)消费的日志。

结论:集群环境中的某一个Mq节点宕掉,不影响消息消费

模拟场景2

当前环境:12的Mq节点已停、13上的Mq节点(Master)正常运行,14上的Mq节点(Slave)正常运行

模拟线上环境操作:停掉13上的Mq节点

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

日志分析:控制台日志卡着不动了,没有任何消息能被消费

结论:只有一台Mq节点正常运行,集群Mq推算不出新的Master,将会一直等集群中的其他Mq节点恢复

模拟场景3

当前环境:12、13上的Mq节点已停、14上的Mq节点(Slave)正常运行(场景2中,14上的Mq并没有被选为Master)

模拟线上环境操作:启动13上的Mq节点

现在14(Slave)是运行的,但此刻并没有选举出Master,我现在,

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

日志分析:过了十几秒,重连上了14,然后继续消费:

结论:集群环境超过半数Mq节点运行正常,那么整个集群环境就是正常的

 

上面是我们模拟了Mq节点出现问题,消息消费的一些情况,由于ActiveMQ集群的高可用,依赖于ZooKeeper集群的高可用,那么我们现在来模拟,zookeeper节点出现异常,将会对ActiveMq有什么影响

 

Ps : zookeeper(下面简称zk节点) 分为Leader[主]、follower[从]

模拟场景1

当前环境:12、13、14上的zk节点、Mq节点都正常运行,13上的zk节点是Leader 、13上的Mq节点是Master

模拟线上环境操作:停掉13上的zk节点:

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

日志分析:14上的Mq节点变成了Master,继续消费消息,消息依然被连续消费

结论:一台zk节点宕掉,虽然Mq会重新选举新的Master节点,单Mq节点不会出现异常,不影响Mq节点消费消息

模拟场景2

当前环境:12、14上的zk节点都正常运行,13上的zk节点已停 |  14上的Mq节点是Master,12、13上的Mq节点(Slave)运行正常

模拟线上环境操作:停掉12上的zk节点:

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

日志分析:控制台日志卡着不动了,linux上我看了下3台Mq节点的状态,发现14上的Mq节点也挂掉了

结论:zk节点超过半数异常,则整个Mq集群环境将处于异常状态

模拟场景2

当前环境:12、13上的zk节点都停了,14上的zk节点运行正常 | 14上的Mq节点挂了,12、13上的Mq节点(Slave)运行正常

模拟线上环境操作:启动12上的zk节点:

基于zookeeper(集群)+LevelDB的ActiveMq高可用集群安装、配置、测试

日志分析:消费正常

结论:超过半数zk节点运行正常,Mq集群环境也会运行正常

模拟场景3

当前环境:所有上的zk节点都是停掉了| 所有Mq节点运行异常

模拟线上环境操作:依次启动所有zk节点:

日志分析:没有任何消息被消费

结论:当zk节点都处于异常状态,重启过后,Mq节点将运行异常,需要重启Mq节点,才能恢复。

 

警告: 请使用者注意。replicatedLevelDB不支持延迟或者计划任务消息。

这些消息存储在另外的LevelDB文件中,如果使用延迟或者计划任务消息,将不会复制到slave Broker上,不能实现消息的高可用。