注:本文以ActiveMQ5.10版本爲基礎。
我們知道,ActiveMQ中的TransportConnector(傳輸連接器)主要用於配置ActiveMQ服務端和客戶端之間的通信方式,NetworkConnector(網絡連接器)則主要用來配置ActiveMQ服務端與服務端之間的通信。在某些場景,網絡拓撲中我們可能會需要大量的生產者和消費者,也就是說我們會有大量的ActiveMQ客戶端,這樣,我們就需要在網絡環境中有多個MQ服務器,服務器之間是可以透傳消息的,這是,我們就需要用到NetworkConnector,我們先從簡單的分析起,假設我們需要部署兩臺MQ服務器,如下圖:
使用NetworkConnector的簡單場景
如上圖所示,服務器S1和S2通過NewworkConnector相連,則生產者P1發送消息,消費者C3和C4都可以接收到,而生產者P3發送的消息,消費者C1和C2同樣也可以接收到,要使用NewworkConnector的功能,需要在服務器S1的activemq.xml中的broker節點下添加如下配置(注:10.79.11.172:61617爲S2的地址):
<networkConnectors>
<networkConnector uri="
static:(tcp://10.79.11.172:61617)
"/>
</networkConnectors>
<networkConnectors>
<networkConnector uri="
static:(tcp://10.79.11.171
:61617)
"/>
</networkConnectors>
<networkConnectors>
<networkConnector uri="
static:(tcp://10.79.11.171
:61617,tcp://10.79.11.173:61617,tcp://10.79.11.174:61617
)
"/>
</networkConnectors>
<networkConnector uri="multicast://default"/>
</networkConnectors>
decreaseNetworkConsumerPriority:默認值爲false,如果該值爲false,網絡上的消費者和本地的消費者有相同的優先級,就是說一個消息發送到本地的消費者和其他的網絡消費者有相同的概率。如果該值爲true,則其他網絡消費者的優先級從-5開始算起,根據網絡跳數(network hops)來算優先級,當然是越“遠”優先級越低。
networkTTL:默認值爲1,該值表示消息或訂閱可以通過的消息提供者(brokers)的數量。拿上圖來說,假設P1向S1發了條消息,另外有個ActiveMQ服務器S3(上圖未畫出)與S2相互橋接,但不直接與S1橋接,因爲該值爲1,即使S3上有該隊列的消費者或主題的訂閱者,但對於S1來說S3這些網絡消費者和訂閱者是不可見的,所以P1發的這條消息就不能被S3上的消費者給消費,如果想要讓S3上的消費者也有機會消費,可以讓S3和S1橋接,或者將S1的networkTTL參數配置爲2.
messageTTL:默認爲1,從5.9版本開始有效,表示消息能通過的消息提供者數量,該值可以覆蓋掉networkTTL中對消息通過數量的限制。
consumerTTL:默認爲1,從5.9版本開始有效,表示訂閱能通過的消息提供者數量,該值可以覆蓋掉networkTTL中對訂閱通過數量的限制。
conduitSubscriptions:默認爲true。該值表示多個消費者訂閱一個相同的目的地是否在網絡上被對待爲一個消費者。以上圖爲例,如果採用默認的分配策略,P1連續發120條消息,結果應該是C1和C2都收到40條,而C3和C4共收到40條(C3和C4平分這40條),爲什麼不是C1、C2、C3和C4都收到大概30條呢?因爲該值爲true,C3和C4對於S1來說只是一個消費者,而不是兩個。注意,如果你的多個網絡提供者中的消費者使用了消息選擇器(selector),你又設置了conduitSubscriptions爲true,則有可能會導致消息不會被髮送到正確的網絡消費者從而消息不被消費,因爲網絡消費者中的消息選擇器對生產者的提供者來說是透明的,所以此種情況下,請將conduitSubscriptions設置爲false。
excludedDestinations:默認爲空,用來配置不會在網絡中轉發的目的地(Destination)。
dynamicallyIncludedDestinations:默認爲空,用來配置可以在網絡中轉發的目的地,和上面的excludedDestinations的功能相反。例如:
<networkConnector uri="static:(tcp://host)">
<dynamicallyIncludedDestinations>
<queue physicalName="queue1"/>
<topic physicalName="topic1"/>
</dynamicallyIncludedDestinations>
</networkConnector>
staticallyIncludedDestinations:默認爲空,用來配置可以在網絡中轉發的目的地,但它和dynamicallyIncludedDestinations不同的是dynamicallyIncludedDestinations只在對方有該目的地的消費者時纔將消息轉發給對方,staticallyIncludedDestinations則不管對方有沒有該目的地都將消息轉發給對方。
舉例配置如下:
<networkConnectors>
<networkConnector uri="static:(tcp://0.0.0.0:61616,tcp://0.0.0.0:61618)" >
<staticallyIncludedDestinations>
<queue physicalName="TopicTestQueue1"/>
</staticallyIncludedDestinations>
</networkConnector>
</networkConnectors>
duplex:默認值爲false,默認情況下,在兩個提供者之間的連接上的消息流動方向是單向(單工連接),如果該值設置爲true,則一個連接上可以雙向流動消息(雙工連接)。可以想象,單工連接比雙工連接吞吐量要高,但增加了連接數量方面的開銷。如果在使用雙工連接時爲了增加吞吐量,可以建立多個雙工連接,但每個連接必須起不同的名字,例如:
<networkConnectors>
<networkConnector name="SYSTEM1" duplex="true" uri="static:(tcp://10.79.6.56:61616)">
<dynamicallyIncludedDestinations>
<topic physicalName="outgoing.System1" />
</dynamicallyIncludedDestinations>
</networkConnector>
<networkConnector name="SYSTEM2" duplex="true" uri="static:(tcp://10.79.6.56:61616)">
<dynamicallyIncludedDestinations>
<topic physicalName="outgoing.System2"/>
</dynamicallyIncludedDestinations>
</networkConnector>
</networkConnectors>
prefetchSize:默認是1000,指網絡連接中的消費者的預讀數量,該值必須大於0,因爲網絡消費者不能採用poll來獲取消息(輪詢消息)。
suppressDuplicateQueueSubscriptions:(從5.3版本開始有效)默認爲false,如果該參數爲true,會防止提供者之間相互橋接時的隊列重複訂閱的問題,其實該參數爲true和false只是ActiveMQ代碼中的微妙的性能變化,對實際的集羣結果並不會帶來什麼影響。
bridgeTempDestinations:默認值爲true,該值用來指定在MQ服務器在網絡中創建臨時目的地(temp destinations)時是否需要廣播公告消息(broadcast advisory messages )。如果設置爲false,表示禁用此功能,則當生產者和消費者不是連接到同一個MQ服務器時,可以減少網絡開銷。
alwaysSyncSend:(從5.6版本開始有效)默認爲false,表示是否總是異步發送。默認時,非持久化消息被髮送到遠程的MQ服務器時將採用請求/應答方式而不是oneway方式。此參數對待持久化和非持久化消息相同。
staticBridge:(從5.6版本開始有效)默認爲false,如果設置爲true,MQ服務器將不會動態應答新的消費者,也意味着該提供者將對其他遠程提供者的主題不感興趣。當設置爲true是,我們可以使用staticallyIncludedDestinations來創建配置需要訂閱的主題,例如:
<networkConnector uri="static:(tcp://host)"
staticBridge="true">
<staticallyIncludedDestinations>
<queue physicalName="always.include.queue"/>
</staticallyIncludedDestinations>
</networkConnector>
消息如果一開始就是持久化的化的或者是被持久訂閱的,則在網絡經紀人中傳播時也會保持這種特性,然而,如果消息一開始就不是持久化的或者不是持久訂閱的,則在網絡的MQ服務器中傳播時也一定不會有這些特性。
總的消息順序在網絡經紀人中是不保證的,當然,即使不是網絡經紀人,在單個經紀人環境下,有多個消費者時,消息被消費的順序也是不保證的。
如果你希望提供者不受任何遠程提供者上消費者的影響,或者希望不管遠程提供者上是否有消費者都將所有消息轉發到遠程提供者,那麼你可以考慮使用靜態網絡(static networks)。
就如前面你說看到的,如果你想增加吞吐量,或者想採用不同的通信方式(如tcp或者nio),又或者你想採用更靈活的配置,兩個提供者之間可以由多個NetworkConnector相連, 例如,如果使用分佈式隊列(distributed queues),你可能希望在通過網絡對隊列接收者能採用等效加權(equivalent weighting),但只針對活躍的接收者,你可以如下配置:
<networkConnectors>
<networkConnector uri="static:(tcp://localhost:61617)" name="queues_only" conduitSubscriptions="false" decreaseNetworkConsumerPriority="false">
<excludedDestinations>
<topic physicalName=">"/>
</excludedDestinations>
</networkConnector>
</networkConnectors>
<policyMap>
<policyEntries>
<policyEntry queue="TEST.>" enableAudit="false">
<networkBridgeFilterFactory>
<conditionalNetworkBridgeFilterFactory replayWhenNoConsumers="true"/>
</networkBridgeFilterFactory>
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>
感興趣的童鞋可以去看看官方文檔:http://activemq.apache.org/networks-of-brokers.html