`
y806839048
  • 浏览: 1080820 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

activemq单集群--伪集群和主从高可用使用

阅读更多
一、本文目的
        介绍如何在同一台虚拟机上搭建高可用的Activemq服务,集群数量包含3个Activemq,当Activemq可用数>=2时,整个集群可用。
        本文Activemq的集群数量为3个,分别命名为mq1,mq2,mq3
 高可用的原理

 HA(高可用性)几乎在所有的架构中都需要有一定的保证,在生产环境中,我们也需要面对broker失效、网络故障等各种问题,ActiveMQ也不例外。activeMQ作为消费分发和存储系统,它的HA模型只有master-slave,我们通过broker节点“消息互备”来达成设计要求。M-S架构中,只有master开启transportConnector(里面囊括需要通信的所有节点,这些节点随时可以转化成master),slave不开启,所以客户端只能与master通讯,客户端无法与slave建立连接(可以自动切换,只是区别有无存储共享)。

 

    Client端与master交互并生产和消息消息,并且有一个或者多个slave与其保持同步,如果master失效,我们希望slave能够自动角色转换并接管服务,并且故障转移的过程不能影响Client对消息服务的使用(failover)。ActiveMQ Broker不仅仅负责消息的分发,还需要存储消息,根据存储机制的不同,master-slave模式分为两种:“Shared nothing”和“Shared storage”。其中“Shared nothing”表明每个broker有各自的存储机制,各个broker之间无任何数据共享(仍有同步),这是最简单的部署方案,当然也是数据可靠性最低的,如果一个broker存储设备故障将会导致此broker中的数据需要重建,master与slave之间的状态感知,是通过TCP通信来实现。“Shared storage”是推荐的架构方案,master与slave之间共享远端存储系统(比如JDBC Storage,SAN分布式文件系统等)(由于是共享不需要同步数据(消息的持久化需要另外设置),也有共享用来实现排它锁选主,防止脑裂),master与slave通过获取Storage的排他锁状态来感知状态,获取锁的broker作为master并负责与Client数据交互,当锁失效后slave之间通过锁竞争来产生新的master,在最新的架构中,zookeeper也可以很方便的集成到ActiveMQ中。

master-slave并不是大规模消息系统的扩展方案,它只是解决broker节点的HA问题,稍后我们会介绍“Forward Brige”模式在activeMQ分布式系统中的应用。

 

使用ZooKeeper(集群)注册所有的ActiveMQ Broker。只有其中的一个Broker可以提供服务,被视为Master,其他的Broker处于待机状态, 被视为Slave。 如果 Master 因故障而不能提供服务,ZooKeeper 会从 Slave 中选举出一个Broker充当Master。

  Slave连接Master并同步他们的存储状态,Slave 不接受客户端连接。所有的存储操作都将被复制到

连接至Master的Slaves。如果 Master 宕了,得到了最新更新的Slave会成为Master。故障节点在恢复后会重新加入到集群中并连接Master进入Slave模式。

  所有需要同步的 disk 的消息操作都将等待存储状态被复制到其他法定节点的操作完成才能完成。所

以,如果你配置了 replicas=3,那么法定大小是(3/2)+1=2。Master将会存储并更新然后等待 (2-1)=1 个

Slave 存储和更新完成,才汇报success。至于为什么是 2-1,熟悉Zookeeper的应该知道,有一个node

要作为观擦者存在。当一个新的Master 被选中,你需要至少保障一个法定node在线以能够找到拥有最新

状态的node。这个node可以成为新的 Master。因此,推荐运行至少3个replica nodes,以防止一个node

失败了,服务中断。(原理与ZooKeeper集群的高可用实现方式类似)

主要用来1,同步存储(节点),2,选主(获取锁的就是主)

 

master-slave  Shared nothing  会出现脑裂   Shared storage  提供共享持久化 并通过共享插件 中锁的机制避免了脑裂(原因是由于采用sharing store ,共享文件系统,有锁,获取锁的才是主,网络不稳定断开的master,其他从重新选还是获取不到master的锁(master还在不会释放))

 

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

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

           bind:集群间通讯的ip和端口

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

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

           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>

4、启动activemq

      /usr/local/src/activemq1/bin/activemq start

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

 

5、关于管控台

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

 

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

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

2、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();
          }
      }
  }

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

 

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

a)   此时的ZooInspetor

 

5、重启mq2队列(重启后mq2加入队列成为Slaver,但是mq1还是Master,队列不受影响)

 

6、关闭mq1、mq2,仅剩mq3(由于只有一个队列,无法进行选举,所以整个队列都无法提供服务)


 

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

a) ZooInspecto显示mq1被选举为Master

b) 程序重新向队列消息,数据并没有中断 

 

五、总结

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

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

 

六、参考资料

1、http://www.cnblogs.com/gossip/p/5970090.html

2、http://activemq.apache.org/replicated-leveldb-store.html

 3,https://www.cnblogs.com/hapjin/articles/5665733.html

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics