Clustering(集)
ActiveMQ从多种不同的方面提供了集的支持。
1、 Queue consumer clusters
ActiveMQ支持订阅同一个queue的consumers上的集。如果一个consumer失效,那么所有未被确认(unacknowledged)的消息都会被发送到这个queue上其它的consumers。如果某个consumer的处理速度比其它 consumers更快,那么这个consumer就会消费更多的消息。
需要注意的是,笔者发现AcitveMQ5.0版本的Queue consumer clusters存在一个bug:采用AMQ Message Store,运行一个producer,两个consumer,并采用如下的配置文件:
Xml代码
<beans> <broker xmlns="/config/1.0" brokerName="BugBroker1" useJmx="true"> <transportConnectors> <transportConnector uri="tcp://localhost:61616"/> </transportConnectors> <persistenceAdapter> <amqPersistenceAdapter directory="activemq-data/BugBroker1" maxFileLength="32mb"/> </persistenceAdapter> </broker> </beans> |
那么经过一段时间后可能会报出如下错误:
ERROR[ActiveMQTransport:tcp:///127.0.0.1:1843-RecoveryListenerAdapter.java:58-RecoveryListenerAdapter] Message id ID:versus-1837-1203915536609-0:2:1:1:419 could not be recovered from the data store!
Apache官方文档说,此bug已经被修正,预定在5.1.0版本上体现。
2、 Broker clusters
一个常见的场景是有多个JMS broker,有一个客户连接到其中一个broker。如果这个broker失效,那么客户会自动重新连接到其它的broker。在ActiveMQ中使用failover:// 协议来实现这个功能。ActiveMQ3.x版本的reliable://协议已经变更为failover://。
如果某个网络上有多个brokers而且客户使用静态发现(使用Static Transport或Failover Transport)或动态发现(使用Discovery Transport),那么客户可以容易地在某个broker失效的情况下切换到其它的brokers。然而,stand alone brokers并不了解其它brokers上的consumers,也就是说如果某个broker上没有consumers,那么这个broker上的消息可能会
因得不到处理而积压起来。目前的解决方案是使用Network of brokers,以便在broker之间存储转发消息。ActiveMQ在未来会有更好的特性,用来在客户端处理这个问题。
从ActiveMQ1.1版本起,ActiveMQ支持networks of brokers。它支持分布式的queues和topics。一个broker会相同对待所有的订阅(subscription):不管他们是来自本地的客户连接,还是来自远程broker,它都会递送有关的消息拷贝到每个订阅。远程broker得到这个消息拷贝后,会依次把它递送到其内部的本地连接上。有两种方式配置Network of brokers,一种是使用static transport,如下:
Xml代码
1. <broker brokerName="receiver" persistent="false" useJmx="false"> 2. <transportConnectors> 3. <transportConnector uri="tcp://localhost:62002"/> 4. </transportConnectors> 5. <networkConnectors> 6. <networkConnector uri="static:( tcp://localhost:61616,tcp://remotehost:61616)"/> 7. </networkConnectors> 8. … 9. </broker> |
另外一种是使用multicast discovery,如下:
Xml代码
1. <broker name="sender" persistent="false" useJmx="false"> 2. <transportConnectors> 3. <transportConnector uri="tcp://localhost:0" discoveryUri="multicast://default"/> 4. </transportConnectors> 5. <networkConnectors> 6. <networkConnector uri="multicast://default"/> 7. </networkConnectors> 8. ... 9. </broker> |
Network Connector有以下属性:
Property Default Value Description
name bridge name of the network - for more than one network connector between the same two brokers - use different names dynamicOnly false if true, only forward messages if a consumer is active on the connected broker decreaseNetworkConsumerPriority false decrease the priority for dispatching to a Queue consumer the further away it is (in network hops) from the producer networkTTL 1 the number of brokers in the network that messages and subscriptions can pass through conduitSubscriptions true multiple consumers subscribing to the same destination are treated as one consumer by the network excludedDestinations empty destinations matching this list won't be forwarded across the network dynamicallyIncludedDestinations empty destinations that match this list will be forwarded across the network n.b. an empty list means all destinations not in the excluded list will be forwarded staticallyIncludedDestinations empty destinations that match will always be passed across the network - even if no consumers have ever registered an interest duplex false if true, a network connection will be used to both produce AND Consume messages. This is useful for hub and spoke scenarios when the hub is behind a f
irewall etc.
关于conduitSubscriptions属性,这里稍稍说明一下。设想有两个brokers,分别是brokerA和brokerB,它们之间用 forwarding bridge连接。有一个consumer连接到brokerA并订阅queue:Q.TEST。有两个consumers连接到brokerB,也是订阅queue:Q.TEST。这三个consumers有相同的优先级。然后启动一个producer,它发送了30条消息到brokerA。如果 conduitSubscriptions=true,那么brokerA上的consumer会得到15条消息,另外15条消息会发送给brokerB。此时负载并不均衡,因为此时brokerA将brokerB上的两个consumers视为一个;如果 conduitSubscriptions=false,那么每个consumer上都会收到10条消息。以下是关于NetworkConnector属性的一个例子:
Xml代码
1. <networkConnectors> 2. <networkConnector uri="static://(tcp://localhost:61617)" 3. name="bridge" dynamicOnly="false" conduitSubscriptions="true" 4. decreaseNetworkConsumerPriority="false"> 5. <excludedDestinations> 6. <queue physicalName="st.foo"/> 7. <topic physicalName="st.bar"/> 8. </excludedDestinations> 9. <dynamicallyIncludedDestinations> 10. <queue physicalName="st.foo"/> 11. <topic physicalName="st.bar"/> active transport12. </dynamicallyIncludedDestinations> 13. <staticallyIncludedDestinations> 14. <queue physicalName="always.include.queue"/> 15. <topic physicalName="pic"/> 16. </staticallyIncludedDestinations> 17. </networkConnector> 18. </networkConnectors> |
3、Master Slave
在一个网络内运行多个brokers或者stand alone brokers时存在一个问题,这就是消息在物理上只被一个broker持有,因此当某个broker失效,那么你只能等待直到它重启后,这个 broker上的消息才能够被继续发送(如果没有设置持久化,那么在这种情况下,消息将会丢失)。Master Slave 背后的想法是,消息被复制到slave broker,因此即使master broker遇到了像硬件故障之类的错误,你也可以立即切换到slave broker而不丢失任何消息。
Master Slave是目前ActiveMQ推荐的高可靠性和容错的解决方案。以下是几种不同的类型:
Master Slave Type Requirements Pros Cons
Pure Master Slave None No central point of failure Requires manual restart to bring back a failed master and can only support 1 slave Shared File System Master Slave A Shared File system such as a SAN Run as many slaves as required. Automatic recovery of old masters Requires shared file system JDBC Master Slave A Shared database Run as many slaves a
s required. Automatic recovery of old masters Requires a shared database. Also relatively slow as it cannot use the high performance journal
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论