ActiveMQ Master Slave集群

人生是海洋,希望是舵手的罗盘,使人们在暴风雨中不致迷失方向。 —— 狄德罗

1. 前言

  ActiveMQ Master/Slave集群可以提高ActiveMQ的高可用性,一旦一个Broker出现故障不可用时,另一个Broker可以迅速代替其成为Master角色。Master/Slave集群不支持负载均衡,仅能解决单点故障。
  ActiveMQ 提供了三种集群配置方式:

  • 基于共享文件系统(KahaDB)
  • 基于JDBC
  • 基于可复制的Level DB + Zookeeper

2. 基于共享文件系统(KahaDB)

  我们在同一台机器上部署两个Broker来模拟集群,若是分别在两台机器上部署,还需要两台机器能共享文件系统。

2.1 修改持久化适配器(persistenceAdapter)

  在activemq1和activemq2的activemq.xml中,找到persistenceAdapter。修改kahaDB的共享文件目录。


     

2.2 修改端口号

  ActiveMQ默认端口是61616,因两Broker的端口不允许重复,因此需要将activemq2的端口更换为另一个端口号。


            
            
 

2.3 启动Broker

  分别启动两个Broker服务器,第一个Broker启动完成后,再接着启动第二个Broker,控制台中的日志如下:

.......
Using Persistence Adapter: KahaDBPersistenceAdapter[F:\develop\tool\activemq-cluster\kahadb]
jvm 1    |  INFO | Database F:\develop\tool\activemq-cluster\kahadb\lock is locked by another server. This broker is now in slave mode waiting a lock to be acquired

  从上面的日志可以看出,因F:\develop\tool\activemq-cluster\kahadb\lock is locked,导致第二个Broker是作为Slave启动的,第一个Broker那就是Master服务器了。
  接着将Master Broker关停后,Slave Broker则迅速代替成为Master。再次启动activemq1,则是以Slave的身份启动的。
  集群启动后,只有率先启动的节点(Master)一直锁定这lock文件,其它节点(Slave)由于不能访问该文件而等待启动。一旦Master节点挂掉,lock文件锁被释放;其它Slave节点中率先锁定lock文件的,成为Master节点。

3. 基于JDBC(以MYSQL为例)

3.1 配置数据库连接池

  分别在两个broker的activemq.xml中增加配置数据库连接池,可添加在标签的后面。



    
    
    
    

需要把mysql的驱动jar包和Druid的jar包放在各节点的lib目录下。

3.2 修改持久化适配器(persistenceAdapter)

  修改persistenceAdapter配置项,注释掉Kahadb的配置,配置上JDBC方式的persistenceAdapter。


      
      
      

  依次启动activemq1和activemq2,发现只有activemq1启动成功,activemq2处于等待获取锁的状态。当抢到锁的broker宕机了,activemq2会抢到锁,成为Master。


ActiveMQ Master Slave集群_第1张图片
activemq1启动时获得锁,且连接数据库成功

ActiveMQ Master Slave集群_第2张图片
activemq2一直阻塞在等待锁

ActiveMQ Master Slave集群_第3张图片
activemq1宕机后,activemq2立即获得锁,然后连接数据库成功

  启动Broker后,会创建activemq_acks、activemq_lock和activemq_msgs三张表。
  (1)activemq_acks:用于存储订阅关系。如果是持久化Topic,订阅者和服务器的订阅关系在这个表保存。
  (2)activemq_lock:在集群环境中才有用,只有一个Broker可以获得消息,称为Master Broker,其他的只能作为备份等待Master Broker不可用,才可能成为下一个Master Broker。这个表用于记录哪个Broker是当前的Master Broker。
  (3)activemq_msgs:用于存储消息,Queue和Topic都存储在这个表中。

  使用生产者产生消息,会存放在表activemq_msgs中:


ActiveMQ Master Slave集群_第4张图片

  启动消费者消费这些消息后:


4. 基于可复制LevelDB + Zookeeper

  Leveldb是一个google实现的非常高效的kv数据库,是单进程的服务,能够处理十亿级别规模Key-Value型数据,占用内存小。
  基于可复制LevelDB的集群方案,需要引入ZooKeeper。根据ZooKeeper的使用方式可以分为单节点的ZooKeeper和Zookeeper集群。这里我们只讲述ZooKeeper集群,单节点不是一个可靠的选择。

4.1 Zookeeper集群配置

  ZooKeeper分部署在下面三个目录中。

F:\develop\tool\activemq-cluster\zookeeper1
F:\develop\tool\activemq-cluster\zookeeper2
F:\develop\tool\activemq-cluster\zookeeper3
4.1.1 配置zoo.cfg

  把3个节点中config目录下的zoo_sample.cfg复制一份,改成zoo.cfg。
  因为是在一台主机上部署,所以每个zoo.cfg中的clientPort不能重复;如果有三台主机,那么采用默认的clientPort就行,同理server.1、server.2、server.3可以写作<各自ip>:2888:3888。
其中zookeeper1中的配置如下:

#默认配置
tickTime=2000
initLimit=10
syncLimit=5
#需要修改的配置
dataDir=D:/MQ/apache-activemq/cluster/zkdata/z1/
clientPort=2181
server.1=localhost:2888:3888
server.2=localhost:2889:3889
server.3=localhost:2890:3890

zookeeper2中的配置如下:

#默认配置
tickTime=2000
initLimit=10
syncLimit=5
#需要修改的配置
dataDir=D:/MQ/apache-activemq/cluster/zkdata/z2/
clientPort=2182
server.1=localhost:2888:3888
server.2=localhost:2889:3889
server.3=localhost:2890:3890

zookeeper3中的配置如下:

#默认配置
tickTime=2000
initLimit=10
syncLimit=5
#需要修改的配置
dataDir=D:/MQ/apache-activemq/cluster/zkdata/z3/
clientPort=2183
server.1=localhost:2888:3888
server.2=localhost:2889:3889
server.3=localhost:2890:3890
4.1.2 配置myid

4.1.2 myid

创建三个目录

F:\develop\tool\activemq-cluster\zkdata\z1
F:\develop\tool\activemq-cluster\zkdata\z2
F:\develop\tool\activemq-cluster\zkdata\z3

  每个目录中都创建一个名为myid的文件(文本文件,删掉txt后缀),3个文件的内容分别写1、2、3。

F:\develop\tool\activemq-cluster\zkdata\z1\myid   1
F:\develop\tool\activemq-cluster\zkdata\z2\myid   2
F:\develop\tool\activemq-cluster\zkdata\z3\myid   3

4.2 ActiveMQ配置

  在3个amq节点中配置activemq.xml中的持久化适配器。根据以下配置示例,修改其中bind、zkAddress和hostname。如果你是在三台主机上部署,那么bind项可以写成bind="tcp://0.0.0.0:0",默认采用61619端口。我们这里在一台主机上演示,因此需要保证bind端口不冲突。
activemq1的配置如下:


    ......
    
        
    
    ......

activemq2的配置如下:


    ......
    
        
    
    ......

activemq3的配置如下:


    ......
    
        
    
    ......

注意无论是master节点还是salve节点,它们的brokerName属性都必须一致,
否则activeMQ集群就算连接到了zookeeper,也不会把他们当成一个Master/Salve组。

4.3 ActiveMQ配置

  先依次启动ZooKeeper,再依次启动ActiveMQ。启动第1个Zookeeper时,控制台会报连接错误,因为其它的ZooKeeper节点还没启动。

  第一个Broker启动后,会成为Master。


ActiveMQ Master Slave集群_第5张图片
Master启动日志

  随后启动的Broker都会成为slave。


ActiveMQ Master Slave集群_第6张图片
slave1启动日志

ActiveMQ Master Slave集群_第7张图片
slave2启动日志

  当Master Broker宕机后,剩余的slave会竞争成为Master。

4.3 注意点

  对于replicas属性,官方给出的解释如下:

The number of nodes that will exist in the cluster. At least (replicas/2)+1 nodes must be online to avoid service outage.(default:3)

  这里的“number of nodes”包括了Master节点和Salve节点的总和。换句话说,如果您的集群中一共有3个ActiveMQ节点,且只允许最多有一个节点出现故障。那么这里的值可以设置为2(当然设置为3也行,因为整型计算中 3 / 2 + 1 = 2)。但如果您将replicas属性设置为4,就代表不允许3个节点的任何一个节点出错,因为:(4 / 2) + 1 = 3,也就是说3个节点是本集群能够允许的最小节点数。

  一旦zookeeper发现当前集群中可工作的ActiveMQ节点数小于所谓的“At least (replicas/2)+1 nodes”,在ActiveMQ Master节点的日志中就会给出提示:“Not enough cluster members connected to elect a master.”,然后整个集群都会停止工作,直到有新的节点连入,并达到所规定的“At least (replicas/2)+1 nodes”数量。

  bind属性指明了当本节点成为一个Master节点后,通过哪一个通讯位置进行和其它Salve节点的消息复制操作。注意这里配置的监听地址和端口不能在transportConnectors标签中进行重复配置,否则节点在启动时会报错。

  zkAddress属性指明了连接的zookeeper服务节点所在的位置。如果您有多个zookeeper服务节点,那么请依次配置这些zookeeper服务节点的位置,并以“,”进行分隔。

你可能感兴趣的:(ActiveMQ Master Slave集群)