原文地址:
http://activemq.apache.org/clustering.html
(第一次翻译,如有不足,欢迎指正)
集群是一个很大的范围总是意味着不同的事对不同的人, 此处我们将列出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
上例中会在3秒后使发送失败如果3秒后连接未就绪。但是连接不会被终止,所以某些情况下你可以继续尝试使用同一个连接来发送消息(假如某些broker会再次上线),failover的timeout参数
从activeMQ5.3开始可用
Transactions
默认情况下failover是会跟踪事务的,正在使用的事务在重新连接的时候会重新运行。在简单的情况下这就足够了。但我们可以假设这样的一种事务情况,就是前一个已经收到了的
消息在重新连接的时候会被转发。但这并不会总是发生当有许多的连接和许多consumer的时候,因为重新转发的顺序并没有得到保证。可能会有老旧的过期的确认消息影响新的消息的转发,潜在的导致未确认消息的产生。
从5.3.1开始,重新转发的顺序会被追踪并且事务会提交
失败(抛出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:
</<transportConnectors>
...
</broker>
|
如果updateClusterClients设置为真,那么你的客户端只用集群中的第一个可以连接的broker就可以了,如下:
failover://tcp://primary:61616
当有新的broker加入的时候,客户端可连接的broker uri会自动被更新当发生network错误或者broker下线的时候
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
运行多个独立的broker或者一个网络broker集群的问题在于消息在任何时刻都只属于一个物理broker, 如果这个broker下线了,在消息能被传递之前你必须等待这个broker restart.(如果你用的是非持久存储模式,一个broker下线就意味着你损失掉了在这个broker上的信息)
MasterSlave背后的想法就是消息会被复制到slave broker中,这样即使你连接的Master machine(http://activemq.apache.org/masterslave.html)遇到了灾难性的硬件错误, 文件系统或者数据错误,你也能直接的failover到slave机器并且不会有消息的丢失。