1. 程式人生 > >ActiveMQ的叢集配置

ActiveMQ的叢集配置

原文地址:

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://0.0.0.0:61616" updateClusterClients="true" updateClusterFilter="*A*,*B*" /> </<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機器並且不會有訊息的丟失。