(第一次翻译,如有不足,欢迎指正)


集群是一个很大的范围总是意味着不同的事对不同的人, 此处我们将列出ActiveMQ的各种集群


1. Queue consumer cluster

我们在不同的消费者之间提供了一个可靠的高性能的负载均衡的消息队列,如果一个消费者意外掉线了,所有这个消费者未应答的消息都将被重新分发给这个队列中的其他消费者。如果一个消息费比其他消费者都快,它会从列队中获得更多的消息,如果某个消费者很慢,其他消费者会处理更多的消息。所以当所有消费者都连接到同一Queue消息队列的时候,你就拥有了一个可靠的负载均衡的消费者集群。

像这样使用队列的情况,连接一个Network of broker集群能提供了一个更好的网状(grid  style model)的处理模型,它允许集群中的消费者进程去异步的处理队列中的消息通过一个可伸缩的SEDA(An Architecture for Highly Concurrent Server Applications)风格的方式。许多人希望得到一个网络的解决方案可以允许server规范的处理大量的任务,比如一个复杂的计算等等。 大多数情况下, ActiveMQ的Net work of broker和配置failover://transport 的客户端配置都能解决这样的问题。


2. Broker Cluster


JMS环境中最常见的集群模型就是许多的JMS Broker和一个链接到它们中任意一个的JMS client,然后当某一个jms broker掉线之后,这个客户端会自动链接到其他的broker上。


我们在JMS客户端上使用failover:// (1) 协议来实现这样的功能。注意:ActiveMQ3.0中的 reliable:// 已经被failover://替换


如果我们只是在网络上运行多个broker,然后使用static discovery静态发现(http://activemq.apache.org/static-transport-reference.html)或dynamic discovery动态发现(http://activemq.apache.org/discovery-transport-reference.html)协议将Broker的信息告诉客户端,那么客户端会很容易的failover从一个broker到另一个broker。


然后单独的brokder并不知道网络中其他broker上都有哪些客户端连接,所以如果有一个broker没有客户端连接,那么所有发送到这个broker的信息都会被堆积起来并且得不到处理,在客户端端上,我们有一个过时的feature request去处理这个问题--但是现在这个问题的解决方案是创建一个Network of brokers群,然后在这些brokers之间存储和转发信息。



(1):


1:how to configure the failover protocol(怎样配置failover协议)


原文地址:http://activemq.apache.org/failover-transport-reference.html



failover在所有协议上都有效(tcp, ssl, nio ...)(在ActiveMQ 3中也被称Reliable transport)


failover配置语法允许你指定任意数量的uris, failover协议会任意的选一个URI然后尝试着创建一个链接,如果在这个URI上的连接总是不成功或者连接总是失败,


那么会自动选择uri队列中的一个新的uri来进行连接。


配置语法


failover:(uri1,...,uriN)?transportOptions


or
failover:uri1,...,uriN


failover默认使用随机的uri来链接让你可以在许多的brokers中达到负载均衡的效果


如果你更像连接一个主要的uri,并且仅在主要的uri不可用或者掉线的情况下才连接作为备份的第二个uri,你可以像下面这样配置:


failover:(tcp://primary:61616,tcp://secondary:61616)?randomize=false


--如上面方式配置连接之后,如果primary机器掉线,此时连接会自动转移到seconday机器上,但是此时如果primary又上线了,连接是不会自动转移到primary机器上的。


如果想让它自动转义回primary怎么办呢? 当然办法一定是有的,就是增加参数:priorityBackup=true,修改后的uri如下:


failover:(nio://primary:61616,nio://secondary:61616)?randomize=false&priorityBackup=true


--此处还有个问题,就是primary挂掉的时候,如果primary的队列里面还有很多未处理的信息,这些信息会不会被传送到secondary上再继续被处理呢? 答案是不会的。




Transport Options部分太多,请参见原文..




Notes


如果你是用failover,在某些情况下broker下线了,默认情况下你产生消息的方法会被阻塞。用TransportListener会对这个情况有帮助,最好将这个listener直接设置到


ActiveMQContionFactory上,这样它会获取到任何的网络连接请求。


另外你也可以使用timeout选项,这样如果在指定的时间内消息还没发送成功,那该条消息就会发送失败,timeout选项配置如下:


failover:(tcp://primary:61616)?timeout=3000


从activeMQ5.3开始可用




Transactions


默认情况下failover是会跟踪事务的,正在使用的事务在重新连接的时候会重新运行。在简单的情况下这就足够了。但我们可以假设这样的一种事务情况,就是前一个已经收到了的


消息在重新连接的时候会被转发。但这并不会总是发生当有许多的连接和许多consumer的时候,因为重新转发的顺序并没有得到保证。可能会有老旧的过期的确认消息影响新的消息的转发,潜在的导致未确认消息的产生。


失败(抛出TransactionRolledBackException)如果过期的消息在failover之后未被重新转发。另外,一个in doubt  transaction会导致回滚,这样消息就能被应用重新处理了(比如重新被consumer接收)。in doubt transaction会在发生failover并且有事务正在使用的时候发生。我们 不可能去准确的知道事务失败在哪儿,如事务有没有在消息重新转发时提交或者事务仅仅是提交一个消息遗失的回复?这种情况下,回滚是有必要的这样应用就能得到一个确切的失败信息并且可以处理任何潜在的问题。




Broker side Options for Failover


这是5.4版本开始的新特性


Broker的TransportConnector有一些可用选项,可以用来自动更新客户端信息关于新的可以用来failover的broker,如下:


选项名称

默认值

描述

updateClusterClients

false

如果为真,会当broker集群的拓扑结构有更新时自动传送信息通知已连接的客户端

rebalanceClusterClients

false

如果为真,当有新的broker加入到broker集群中的时候所有已连接的客户端会在新的brokder集群中实现平衡

updateClusterClientsOnRemove

false

如果为真,当有brokder从集群中移除的时候会更新已连接的客户机(Having this as separate option enables clients to be updated when new brokers join, but not when brokers leave--这句小弟还没理解到..)

updateClusterFilter

null 

只有在逗号分隔的正则表达式列表中的broker才会去更新连接到它上面的客户端信息


broker的xml配置文件配置示例:


<broker>       


                ...       


                <transportConnectors>       


                <transportConnector name="openwire" uri="tcp:        //0.0.0.0:61616" updateClusterClients="true" updateClusterFilter="*A*,*B*" />       


                </<transportConnectors>       


                ...       


        </broker>


failover://tcp://primary:61616



Priority Backup


上面黄色部分已做了说明


3. Discovery of brokers



我们通过static-discovery静态发现(http://activemq.apache.org/static-transport-reference.html)和dynamic-discovery动态发现(http://activemq.apache.org/discovery-transport-reference.html)提供自动发现brokers的方法,如此一来客户也可以检测并连接到一个逻辑组以外的broker,broker可以发现并连接到其他更大网络上的broker







4. Networks of brokers



如果你正在使用client/server或者hub/spoke类型的拓扑结构并且你有很多的client很多的broker。这就有可能其中一个broker只有生产者没有消费者,这样的话消息会在这个broker上堆积,并且得不到处理。为了避免这种情况,ActiveMQ提供了网络连接模式(Network of brokers),该模式可以提供存储和转发消息的功能,具体就是broker之间可以互相传送消息,这样也允许我们在网络连接模式中提供重分发TOPIC和QUEUES的功能(参见:http://activemq.apache.org/how-do-distributed-queues-work.html)。



这允许一个client去连接任意一个broker, 并且当有错误发生的时候可以failover到其他的broker,它提供了从client的角度来观察一个broker集群



网络连接模式允许我们放大client群到一个很大的数量级,因为我们可以运行我们需要的任意多个broker.



你可以把该模式想象成一个client集群去连接一个broker集群同时拥有failover和discovery功能去做成的一个简单的易用的消息结构。



(注:此处的网络连接模式,仅仅只是为了避免集群中的broker只有producer而没有consumer的情况,它会在不同的broker中间传送消息,以便让所有的消息都能有消费者来处理,但是



该模式下不会有消费的备份,在任何时刻,对客户端来说同一个消息都只存在一份,若需要消息备份机制则需要Master Slave的支持,这我们下面会说到)





附上自己做测试时的静态发现和动态发现的配置:



静态发现如下:



<!-- static discovery config-->
		<networkConnectors>
			<networkConnector uri="static:(nio://192.168.9.102:61616)"/>
		</networkConnectors> 
		<transportConnectors>
			<transportConnector uri="nio://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
		</transportConnectors>
		<!-- static discovery config end-->



动态发现(注意动态只会发现集群内加了multicast配置的机器):



<!-- dynamic discovery config-->
		<networkConnectors>
			<networkConnector uri="multicast://default"/>
		</networkConnectors> 
		<transportConnectors>
			<transportConnector uri="nio://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"  discoveryUri="multicast://default"/>
		</transportConnectors>
		<!-- dynamic discovery config end-->






5. Master Slave



MasterSlave背后的想法就是消息会被复制到slave broker中,这样即使你连接的Master machine(http://activemq.apache.org/masterslave.html)遇到了灾难性的硬件错误, 文件系统或者数据错误,你也能直接的failover到slave机器并且不会有消息的丢失。