ActiveMQ(七)_伪集群和主从高可用使用(转)

1、本文目的
        介绍如何在同一台虚拟机上搭建高可用的Activemq服务,集群数量包含3个Activemq,当Activemq可用数>=2时,整个集群可用。
        本文Activemq的集群数量为3个,分别命名为mq1,mq2,mq3
 
2、概念介绍
一、伪集群
      集群搭建在同一台虚拟机上,3个Activemq分别使用不一样的端口提供服务,启用1个为Master,其它2个为Slaver,同一时间仅Master队列提供服务
二、高可用
      3个Activemq服务,同一时间仅Master队列提供服务,当Master队列挂掉后,其它2个Slaver自动选举出1个成为Master,整个队列服务依然可用。当挂掉的队列从新恢复后,自动加入集群。当集群仅剩下1个队列时,整个队列不可用。
三、Activemq集群数据存储方式
      a) kahaDB:文件共享,默认方式
      b) JDBC:数据库共享,支持MySql、Sql Server、Oracle等
      c) LevelDB:数据共享, 本文使用方式,比kahaDB更快,基于索引
 
3、Activemq伪集群的搭建
一、Activemq的端口介绍
      Activemq默认主要使用2个端口,8161(Web管理控制台端口)、61616(提供消息队列服务的端口),若是须要搭建集群,还须要开放集群间通信的端口(主要用于选举Master)
 
二、Activemq集群端口的分配
  Web管理控制台 消息服务接口 集群通信接口
mq1 8161 51511 61601
mq2 8162 51512 61602
mq3 8163 51513 61603
服务接口没有使用默认的61611是由于activemq默认还会使用61613,61614等端口,如何开放端口及配置控制台端口请自行百度
 
三、修改activemq配置
a) 安装activemq,本文使用Activemq版本为5.11.1,安装过程略
b) 修改配置文件activemq.xml,路径为conf/activemq.xml
     一、broker(全部activemq的brokerName必须一致,才能加入同一个集群)
1
< broker xmlns = "http://activemq.apache.org/schema/core" brokerName = "V1MQ" dataDirectory = "${activemq.data}" >

    二、配置levelDB,加载<broker>节点内html

           bind:集群间通信的ip和端口java

           zkAddress:ZooKeeper地址,多个可用,逗号分隔git

           hostname:主机名,可在/etc/hosts中进行配置github

           zkPath:zkPath目录,可在ZooInspetor中进行查看数据库

1
2
3
4
5
6
7
8
9
10
11
< persistenceAdapter >
          <!-- kahaDB directory="${activemq.data}/kahadb"/ -->
          < replicatedLevelDB
              directory = "${activemq.data}/leveldb"
              replicas = "3"
              bind = "tcp://127.0.0.1:61601"
              zkAddress = "192.168.146.130:2181"
              hostname = "V1"
              zkPath = "/activemq/leveldb-stores"
              />
      </ persistenceAdapter >

四、启动activemqapache

      /usr/local/src/activemq1/bin/activemq startsession

      可经过/usr/local/src/activemq1/data/activemq.log查看启动日志并发

 

五、关于管控台异步

       虽然3个activemq都启动了,可是同一时间只有Master对应的管控台可用,Slaver对应的管控台不可用tcp

 

4、结合ZooInspector测试(推荐使用dubbokeeper中查看zookeeper的一个UI插件,https://github.com/dubboclub/dubbokeeper)

一、打开ZooInspector(可自行搜索下载或从群中下载),输入ZooKeeper地址进行监控,若是3个activemq都启动成功,则显示以下:

二、Java测试代码

       代码可参考:http://www.cnblogs.com/gossip/p/5970090.html

       a) 配置集群IP(这里3个activemq的端口分别是51511,51512,51513)

1
2
3
4
5
6
7
8
<!-- 配置JMS链接工厂 -->
< bean id = "connectionFactory" class = "org.apache.activemq.ActiveMQConnectionFactory" >
     < property name = "brokerURL" value = "failover:(tcp://192.168.146.129:51511,tcp://192.168.146.129:51512,tcp://192.168.146.129:51513)" />
     <!--解决接收消息抛出异常:javax.jms.JMSException: Failed to build body from content. Serializable class not available to broke-->
     < property name = "trustAllPackages" value = "true" />
     <!-- 是否异步发送 -->
     < property name = "useAsyncSend" value = "true" />
</ bean >

        b)  测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Test
   public void produceMsg_DefaultQueue() {
       for ( int i = 0 ; i < 10000 ; i++) {
           final String msg = "序号:" +String.valueOf(i) + " " + "这里是向默认队列发送的消息" + new Date().toString();
           System.out.println(msg);
 
           String destination = jmsTemplate.getDefaultDestination().toString();
           jmsTemplate.send( new MessageCreator() {
               public Message createMessage(Session session) throws JMSException {
                   return session.createTextMessage(msg);
               }
           });
 
           try {
               Thread.sleep( 300 );
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }
   }

三、启动Java程序并发送消息

 

四、关闭Master队列(注意此时的Master队列为mq2)

a)   此时的ZooInspetor

 

五、重启mq2队列(重启后mq2加入队列成为Slaver,可是mq1仍是Master,队列不受影响)

 

六、关闭mq一、mq2,仅剩mq3(因为只有一个队列,没法进行选举,因此整个队列都没法提供服务)


 

七、重启mq1(重启mq1后,mq1和mq3选举了Master队列,从而从新对外提供服务)

a) ZooInspecto显示mq1被选举为Master

b) 程序从新向队列消息,数据并无中断 

 

5、总结

        本文演示了activemq伪集群的搭建过程及高可用的测试过程,经过触类旁通能够将activemq部署到不一样的机器上,从而实现相同的功能。

        遗留问题:ZooInspetor的activemq编号是自动生成的,很难发现其对应的队列,请问有没有能够自定义编号的方法,谢谢。