1. MQ现状
1.1. 概述
ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。完全支持JMS1.1和J2EE 1.4规范的JMS Provider实现
1.2. activemq的特性
- 多种语言和协议编写客户端。语言: Java, C, C++, C#, Ruby, Perl, Python, PHP。应用协议: OpenWire,Stomp REST,WS Notification,XMPP,AMQP
- 完全支持JMS1.1和J2EE 1.4规范 (持久化,XA消息,事务)
- 对Spring的支持,ActiveMQ可以很容易内嵌到使用Spring的系统里面去,而且也支持Spring2.0的特性
- 通过了常见J2EE服务器(如 Geronimo,JBoss 4, GlassFish,WebLogic)的测试,其中通过JCA 1.5 resourceadaptors的配置,可以让ActiveMQ可以自动的部署到任何兼容J2EE1.4商业服务器上
- 支持多种传送协议:in-VM,TCP,SSL,NIO,UDP,JGroups,JXTA
- 支持通过JDBC和journal提供高速的消息持久化
- 从设计上保证了高性能的集群,客户端-服务器,点对点
- 支持Ajax
- 支持与Axis的整合
- 可以很容易得调用内嵌JMS provider,进行测试
1.3. 现有方案
利用官方提供的基于network的cluster方案。
1.4. 存在问题
基于cluster的方案,用的版本比较旧5.6,其network之间通道存在tcp半连接问题,导致集群频频出现问题。
目前是,直接采用一台MQ进行业务操作,按现有业务,可以支持现有的高并发。
实际上,目前迫切需要的是进行MQ的高可用,即Master-Slave方案
2. MQ提供的集群方案
2.1. broker-cluster负载方案
Broker-Cluster的部署方式就可以解决负载均衡的问题。Broker-Cluster部署方式中,各个broker通过网络互相连接,并共享queue。当broker-A上面指定的queue-A中接收到一个message处于pending状态,而此时没有consumer连接broker-A时。如果cluster中的broker-B上面由一个consumer在消费queue-A的消息,那么broker-B会先通过内部网络获取到broker-A上面的message,并通知自己的consumer来消费。
2.1.1. static Broker-Cluster部署
<networkConnectors>
<networkConnector uri="static:(tcp:// 0.0.0.0:61617)"duplex="false"/>
</networkConnectors>
2.1.2. Dynamic Broker-Cluster部署
<networkConnectors>
<networkConnectoruri="multicast://default"
dynamicOnly="true"
networkTTL="3"
prefetchSize="1"
decreaseNetworkConsumerPriority="true" />
</networkConnectors>
2.2. master-slave高可用方案
2.2.1. shared filesystem Master-Slave部署方式
主要是通过共享存储目录来实现master和slave的热备,所有的ActiveMQ应用都在不断地获取共享目录的控制权,哪个应用抢到了控制权,它就成为master。
多个共享存储目录的应用,谁先启动,谁就可以最早取得共享目录的控制权成为master,其他的应用就只能作为slave。
2.2.2. shared database Master-Slave方式
与shared filesystem方式类似,只是共享的存储介质由文件系统改成了数据库而已。
2.2.3. Replicated LevelDB Store方式
这种主备方式是ActiveMQ5.9以后才新增的特性,使用ZooKeeper协调选择一个node作为master。被选择的master broker node开启并接受客户端连接。
其他node转入slave模式,连接master并同步他们的存储状态。slave不接受客户端连接。所有的存储操作都将被复制到连接至Master的slaves。
如果master死了,得到了最新更新的slave被允许成为master。fialed node能够重新加入到网络中并连接master进入slave mode。所有需要同步的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失败了,服务中断。
2.3. 方案对比
- broker-cluster的集群在多个broker之间fail-over和 load-balance
- master-slave能fail-over,但是不能load- balance
- 消息在多个broker之间转发,但是消息只存储在一个broker上,一旦失效必须重启,而主从方式master失效,slave实时备份消息。
- jdbc方式成本高,效率低
- master-slave方式中pure方式管理起来麻烦
因此,我们把MASTER/SLAVE和BROKER CLUSTER两者相结合,可以得到一个完全解决方案:即又可以做到集群又可以做到任何一个BROKER如果发生宕机节点消息也不丢失。
3. 最佳方案
3.1. 方案介绍
根据以上方案,结合优缺点,最终我们需要实现集群的高可用和负载均衡,所以结合后,基于zookeeper+network的集群解决方案,具体如下图所示:
集群连接方式如下图:
3.2. 升级策略
针对现在线上使用MQ的现状分析,目前需要首先考虑支持高可用,所以以上方案可进行逐步实施:
1 对现有的MQ升级到最新版本,并测试验证对5.6的兼容性
2 搭建基于zookeeper的Master-Slave集群GA-MQ。
3 在高可用集群GA-MQ和原有MQ之间建立network连接。
4 切换线上生产者到新的集群GA-MQ
5 切换线上消费者到新的集群GA-MQ
6 等待原有MQ消息完全处理完成后,关闭服务。
7 搭建GB-MQ集群,并按照业务进行负载划分。
8 在GA-MQ和GB-MQ之间建立network连接,实现最终方案。
以上每一步,都需要进行严格的测试验证,才可进行生产环境的切换。