1、ActiveMQ 集群(1)
Queue consumer clusters(消费者集群):
简介: 同一个queue,如果一个消费者失效, 那么任何未经确认的消息将会被发送给queue上的其它消费者。如果一个消费者比其它消费者执行的更快,它将会消费更多的消息。如果任何一个消费者执行速度变慢,那么其他消费者将来弥补空缺。所以,消费者在(队列中)处理消息时,可以有一个可靠的负载均衡。
实现原理: 消费者对消息的处理速率可能不同,对于broker而言,它无法意识到哪个消费者处于"空闲"状态,故消费者空闲时主动向broker请求消息,如此还能有一个良好的"负载均衡".
消费者集群不需要特殊的配置,即可使用。
消费者集群,主要用于解决 消费者间的负载均衡。
Broker clusters(MQ集群)
简介: 一个client连接多台broker中的一台(brokerA)。如果brokerA 挂了,那么client可自动重新连接到其它的 broker(brokerB)上。但是,brokerB并不会识别其它broker上的消费者,如果brokerB没有可识别的消费者,那么brokerB上的消息会因为得不到处理而被堆积起来。
目前的解决方案是使用 Network of brokers,在brokers之间实现存储转发消息。
有2种方式实现 broker集群:
(1) 使用网络连接(Network of brokers)方式:
网络连接方式: 通过把多台不同的broker连接在一起,作为一个整体对外提供服务,从而提高整体对外的消息服务能力。通过这种方式,brokers可以共享队列和消费者列表,从而达到分布式队列的目的。
① 可以同时运行任意多个broker和client。(broker集群 + client集群)
② client可连接到任意一台broker上,若这台broker挂了,client可自动重新连 接到另一台broker上。
实现原理: 通过实现静态发现或动态发现,client可以在一台broker挂了之后,自动地监测并且连接到网络中其它的broker上,同时,也可用于一台broker去发现并且连接到网络中其它的broker上。
Netword of brokers的目的: 提供存储和转发消息到另一台broker上,以实现broker负载均衡,提高消息处理能力。
(2) 使用Master/Slave方式:
背景: 由于client属于broker的,若某台broker挂了,消息只能等待broker重启后, 再被继续消费。
所以: 解决方案是,一台broker作为Master,一台broker作为Slave, 实时的把Master上的消息备份到Slave上。若Master挂了,则服务立即切换至Slave上运行。故消息不会丢失。
那么一个broker如何发现其它的broker呢?
通过使用静态发现或动态发现,当某台broker挂了时,client可以自动地监测到并且重新连接到网络中其它的broker上。同时,利用这个协议,broker也可以发现并且连接到网络中其它的broker上。在 ActiveMQ 中,client通过使用 failover:// 协议来实现这个功能。
即: client通过使用failover://协议,若broker挂了,client会自动监测到这种情况并且重新连接到其它的broker上。
Broker通过使用静态发现或动态发现,可以连接到其它的broker上。
英文参考文档:
Broker clusters:
there is a collection of JMS brokers and a JMS client will connect to one of them; then if the JMS broker goes down, it will auto-reconnect to another broker.
We implement this using the failover:// protocol in the JMS client. See the Failover Transport Reference page for details of how to configure the failover protocol.
If we just run multiple brokers on a network and tell the clients about them using either static discovery or dynamic discovery then clients can easily failover from one broker to another. However stand alone brokers don't know about consumers on other brokers; so if there are no consumers on a certain broker messages could just pile up without being consumed. Currently the solution to this problem is to create a Network of brokers to store and forward messages between brokers.
Discovery of brokers
We support auto-discovery of brokers using static discovery or dynamic discovery so clients can automatically detect and connect to a broker from brokers, as well for brokers to discover and connect to other brokers.
Networks of brokers
If you have many clients and many brokers, there is a chance that one broker has producers but no consumers so that messages pile up without being processed. To avoid this ActiveMQ supports a Networks of Brokers which provides store and forward to move messages from brokers with producers to brokers with consumers which allows us to support distributed queues and topics across a network of brokers.
This allows a client to connect to any broker - and fail over to another broker if there is a failure - providing from the clients perspective a cluster of brokers.
Networks of brokers also allows us to scale up to massive number of clients in a network as we can run as many brokers as we need.
You can think of this as a cluster of clients connecting with a cluster of brokers with auto-failover and discovery making a simple and easy to use messaging fabric.
Borker网络连接:
Networks of Brokers目的:提供存储转发消息到另一台broker上。 实现负载均衡,提高消息处理能力。
附加: http://activemq.apache.org/clustering.html
2、ActiveMQ集群(2)
ActiveMQ具有强大和灵活的集群功能,但在使用的过程中会发现很多的缺点,ActiveMQ的集群方式主要有两种:Master-Slave和Broker Cluster。
1、Master-Slave方式:
Master-Slave方式中,只能是Master提供服务,Slave是实时地备份Master的数据,以保证消息的可靠性。当Master失效时,Slave会自动升级为Master,客户端会自动连接到Slave上工作。
Master-Slave模式分为三类:
a、Pure Master Slave
b、Shared File System Master Slave
c、 JDBC Master Slave。
(1) Pure Master Slave(该方式已经被淘汰:)
需要两台Broker,一台作为Master,另一台作为Slave,运行时,Slave通过网络实时从Master处复制数据,同时,如果Slave和Master失去连接,Slave就会自动升级为Master,继续为客户端提供消息服务,如图所示:
实践时,我们使用两台ActiveMQ服务器,一台作为Master,Master不需要做特殊的配置;另一台作为Slave,配置${ACTIVEMQ_HOME}/conf/activemq.xml文件,在<broker>节点中添加连接到Master的URI和设置Master失效后不关闭Slave,代码如下:
<broker xmlns="http://activemq.apache.org/schema/core"
brokerName="pure_slave"
masterConnectorURI="tcp://0.0.0.0:61616"
shutdownOnMasterFailure="false" dataDirectory="${activemq.base}">
<!-- 同时修改Slave的服务端口,如下:-->
<transportConnectors>
<transportConnector name="openwire" uri="tcp://0.0.0.0:61617"/>
</transportConnectors>
</broker>
为了看到实践的效果,Master和Slave的消息持久化介质都是采用MySQL,并且Master和Slave分别连接不同的数据库。
在消息生产者应用和消息消费者应用的Spring配置文件中添加以下红色内容:
<property name="brokerURL" value="failover:(tcp://localhost:61616,tcp://localhost:61617)?initialReconnectDelay=100" />
这种方式只能两台机器做集群,可以起到很好的双机热备功能,但只能失效一次,只能停机恢复Master-Slave结构。
(2) Shared File System Master Slave
介绍: 这种方式是利用共享文件系统做ActiveMQ集群。kahaDB是ActiveMQ下默认的文件系统。
当一个AMQ实例获得了共享文件的锁,这个实例就成为了Master,其它实例即为Slave。如果这时Master挂了,其它AMQ实例会竞争共享文件的锁,获得锁的就成为Master,其它实例还是Slave。
部署时Slave没有限制数,而且自动切换Master不需要人工干预。
官方资料:http://activemq.apache.org/masterslave.html
Shared File System Master Slave模式如图所示:
本例子是在一台机器上运行三个ActiveMQ实例,需要对ActiveMQ的配置文件做一些简单的配置,就是把持久化适配器的存储目录改为本地磁盘的一个固定目录,三个实例共享这个目录,如下:
<persistenceAdapter>
<kahaDB directory="E:/XXX/XXX/XXX/cluster/shared_file/data/kahadb" />
</persistenceAdapter>
然后修改ActiveMQ实例的服务端口和jetty的服务端口,防止端口占用异常。启动三个ActiveMQ实例,就可以进行测试了。
以上配置只能在一台机器进行,如果各个ActiveMQ实例需要运行在不同的机器,就需要用到分布式文件系统了。
(3) JDBC Master Slave
JDBC Master Slave模式和Shared File Sysytem Master Slave模式的原理是一样的,只是把共享文件系统换成了共享数据库。我们只需在所有的ActiveMQ的主配置文件中(${ACTIVEMQ_HOME}/conf/activemq.xml)添加数据源,让所有的数据源都指向同一个数据库即可。
这种方式的集群相对Shared File System Master Slave更加简单,更加容易地进行分布式部署,但是如果数据库失效,那么所有的ActiveMQ实例都将失效。
官方资料:http://activemq.apache.org/masterslave.html
配置概述:
A. 配置上,不存在Master和Slave,所有Broder的配置基本是一样的
B. 多个共享数据源的Broker构成JDBC Master Slave
C. 给每个Broker取一个名字
D. 首先抢到资源(数据库锁)的Broker成为Masetr
E. 其他Broker保持预备状态,定期尝试抢占资源,运行其的Shell中清楚的显示了这一点
F. 一旦Master崩溃,其他Broker尝试抢占资源,最终只有一台抢到,它立刻成为Master
G. 之前的Master即使重启成功,也只能作为Slave等待
配置步骤:
1. 修改持久化适配器为 MySQL:
<persistenceAdapter>
<jdbcPersistenceAdapter dataDirectory="activemq-data" dataSource="#mysql-ds"/>
</persistenceAdapter>
2. 在activemq.xml 添加如下代码:
<!--配置数据源:注意是配在broker标记之外-->
<bean id="mysql-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mq?relaxAutoCommit=true"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
<property name="maxActive" value="200"/>
<property name="poolPreparedStatements" value="true"/>
</bean>
3. 修改每个broker的tcp端口。否则,该端口被占用时会报错。
Eg: <transportConnector name="openwire" uri="tcp://0.0.0.0:61616"/>
<transportConnector name="openwire" uri="tcp://0.0.0.0:61617"/>
<transportConnector name="openwire" uri="tcp://0.0.0.0:61618"/>
4. 测试时,最好为每一个Broker都起一个独立的名字。
Eg: <broker brokerName="broker_01" … />
5. 在 ${ACTIVEMQ_HOME}/lib中添加 MysQL驱动jar包: mysql-connector-java-5.1.7-bin.jar
详情参见资料: http://blog.csdn.net/jiangxuchen/article/details/8004612
客户端连接服务端代码:
ConnectionFactory cf = new ActiveMQConnectionFactory("failover:(tcp://0.0.0.0:61616, tcp://0.0.0.0:61617, tcp://0.0.0.0:61618)");
结论:
JDBC Master Slave模式实现方式稍微复杂一点,可以实现消息的多点热备功能,Master、Slave的交替完全是即时的,自动的,无需重启任何broker;队列可以实现消息的异步和点对点发送。
以上三种方式的集群都不支持负载均衡,但可以解决单点故障(某台broker坏掉)的问题,以保证消息服务的可靠性。
2、Broker Cluster
Broker Cluster方式主要是通过network of Brokers在多个ActiveMQ实例之间进行消息的路由。Broker的集群分为Static Discovery和Dynamic Discovery两种。
(1) Static Discovery集群
Static Discovery集群就是通过硬编码的方式使用所有已知ActiveMQ实例的URI地址。
如:消息生产者应用连接一个ActiveMQ实例,我们暂时称为MQ1,所有的消息都由该实例提供;两个消息消费者应用分别连接另外两个ActiveMQ实例,分别为MQ2和MQ3,两个消息消费者需要消费MQ1上的消息,但它们连接的都不是MQ1,可以通过Static Discovery方式把MQ1上的消息路由到MQ2和MQ3,为了保证消费者不因某个节点的失效而导致不能消费消息,在消费者应用中需要配置所有节点的URI。
配置:
A、生产者的broker不需要特殊的配置
B、修改每个broker的tcp端口
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616"/>
<transportConnector name="openwire" uri="tcp://0.0.0.0:61617"/>
<transportConnector name="openwire" uri="tcp://0.0.0.0:61618"/>
C. 修改每个broker的名字
Eg: <broker brokerName="broker_01" … />
D. 所有的消费者的broker需要添加networkConnectors节点,用于连接到生产者的broker,如:
<networkConnectors>
<networkConnector uri="static:failover://(tcp://localhost:61616)" duplex="true" />
</networkConnectors>
注: 这段配置需要加在<persistenceAdapter>节点的前面。
E、最后,在消费者应用中设置brokerURL的值如:
<property name="brokerURL" value="failover:(tcp://localhost:61616)" />
Static Discovery集群方式有些缺点,如不能解决单点故障问题,若某个Broker失效时,有可能造成数据的丢失,动态添加节点不够智能化。
更加详细的说明与配置请参考:http://activemq.apache.org/networks-of-brokers.html
(2) Dynamic Discovery集群
Dynamic Discovery集群方式在配置broker时,不需要知道所有其它broker的URI地址,只需在所有实例的${ACTIVEMQ_HOME}/conf/activemq.xml文件中添加以下内容:
<networkConnectors>
<networkConnector uri="multicast://default" />
</networkConnectors>
同时在<transportConnectors>节点中添加以下红色部分内容:
<transportConnectors>
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616" discoveryUri="multicast://default" />
</transportConnectors>
最后,注意修改每个broker的activemq.xml的broker名字和tcp端口号。这样就可以实现消息在所有ActiveMQ实例之间进行路由。Dynamic Discovery集群方式的缺点和Static Discovery一样。
从以上的分析可以看出,Master-Slave模式不支持负载均衡,但可以通过消息的实时备份或共享保证消息服务的可靠性,Broker Cluster模式支持负载均衡,可以提高消息的消费能力,但不能保证消息的可靠性。所以为了支持负载均衡,同时又保证消息的可靠性,我们可以采用Msater-Slave+Broker Cluster的模式。
3、分布式ActiveMQ集群
分布式ActiveMQ集群的部署配置细节:
官方资料:http://activemq.apache.org/clustering.html
基本上看这个就足够了,本文就不具体分析配置文件了。
1、Queue consumer clusters:
同一个queue,如果一个consumer失效,那么未被确认的消息都会被发送到这个queue的其它consumer上。如果某个consumer处理消息比较快,那么它将处理更多的消息。
Queue consumer clusters 不需要特殊的配置。
2、Master-Slave高可用性:
主要目的是实现AMQ的高可用性和容错,如果某broker挂了,需要等待它重启才能继续处理消息。而如果消息被复制到slave上,在当master挂了时,可以直接切换到slave导致消息不会丢失。分为3种形式:
(1) pure master-slave。
该方式已经逐渐被淘汰:http://activemq.apache.org/pure-master-slave.html
(2) Shared File System Master Slave。
官方资料:http://activemq.apache.org/masterslave.html
利用共享文件系统:当多台机器上都部署了AMQ时,指定这些机器的一个共享的文件路径作为存储。
存储默认是基于AMQ的kahaDB(底层是文件系统)实现。
当一个AMQ实例获得了共享文件的锁,这个实例就成为了Master,其它实例即为Slave。如果这时Master挂了,其它AMQ实例会竞争共享文件的锁,获得锁的就成为Master,其它实例还是Slave。部署时Slave没有限制数,而且自动切换Master不需要人工干预。(官方资料有详细的过程图片介绍)
(3) JDBC Master Slave。
官方资料:http://activemq.apache.org/masterslave.html
其实与Shared File System一样,只是把共享文件系统换成数据库作为存储。方便实用,但要保证数据库的高可用性。
3、Broker Cluster中的静态与动态发现:
如何让一个broker知道网络上的其它多个broker呢?主要分为静态发现和动态发现两种类型:
(1) The Static Transport(静态发现,包括failover协议)。
官网资料:http://activemq.apache.org/static-transport-reference.html
所谓静态发现:就是将所有已知的broker uri连接时手工进行配置,对client端uri地址做相应修改。
关于failover:当一个client连接到某个broker,而这个broker挂了,客户端就需要自动连接到网络上其它已知的broker上。
AMQ使用failover协议实现该功能,但需要在client连接时将所有broker以硬编码的形式进行配置。
failover协议官方资料:http://activemq.apache.org/failover-transport-reference.html
(2) The Discovery Transport(动态发现)。
官网资料:http://activemq.apache.org/static-transport-reference.html
所谓动态发现,就是部署前不需要知道所有AMQ实例的uri地址,只要进行相关配置,启动后让AMQ自己检测。
需要修改AMQ配置文件,同时client端连接uri地址也要相应修改。
4、Network of Broker:
主要目的是实现负载均衡,提高消息处理能力。
一个client1连接broker1发送消息,另一个client2连接broker2消费消息,这时就需要将broker1上的消息路由到broker2上。而当broker2上的consumer挂了,也需要将消息转发到其它的有consumer的broker上,避免消息大量堆积无法处理,目前的解决方案是Network of Broker。
官方资料:http://activemq.apache.org/networks-of-brokers.html
本文主要对ActiveMQ分布式集群相关知识进行整理总结,具体配置过程见上文中的官方资料,很详细的。
网上一些不错的参考资料:
http://www.doc88.com/p-086413647667.html
http://wenku.baidu.com/view/d0cd7757ad02de80d4d8408a.html
http://bh-keven.iteye.com/blog/1617788