2014-11-24 91 views
7

能有人請解釋發佈到從屬節點時是怎麼回事幕後與多個節點和鏡像方式隊列中的RabbitMQ集羣背後集羣和鏡像隊列的行爲呢?RabbitMQ的場景

從我所讀到的看來,發佈以外的所有操作似乎只發送給主服務器,然後主服務器將這些操作的效果廣播給從服務器(這來自文檔)。根據我的理解,這意味着消費者將始終使用主隊列中的消息。另外,如果我向一個消息發送一個請求給一個從機,那麼這個從機將通過到達主機來獲取該消息來做額外的跳躍。

但是當我發佈到從屬節點會發生什麼?此節點是否會將首先發送消息的信息發送給主服務器?

似乎有奴隸打交道時,許多附加跳,這樣看來,如果你只知道主,你可以有更好的表現。但是,你如何處理主人失敗?那麼其中一名奴隸將被選爲主人,所以你必須知道在哪裏連接?

問這一切,因爲我們使用的是RabbitMQ的集羣HAProxy的前面,所以我們可以從脫鉤我們的應用程序的集羣結構。這樣,無論何時節點完成,HAProxy都會重定向到活節點。但是當我們殺死一個兔子節點時,我們遇到了問題。與兔子的連接是永久的,所以如果失敗了,你必須重新創建它。此外,你必須在這種情況下重新發送消息,否則你將失去它們。

即使所有這些,仍然可能會丟失消息,因爲當我殺死一個節點時(在某些緩衝區中,網絡中的某處),它們可能正在傳輸中。因此,您必須使用交易或發行商確認,以確保在所有鏡像填滿消息後交付。但這裏還有一個問題。您可能有重複的消息,因爲代理可能發送了從未到達生產者的確認(由於網絡故障等)。因此消費者應用程序需要執行重複數據刪除或以冪等方式處理傳入的消息。

是否有避免這種方式?或者我必須決定是否可以丟失幾條消息而不是重複某些消息?

回答

14

有人能解釋一下在一個RabbitMQ集羣中有多個節點和隊列以鏡像的方式發佈到一個從節點時幕後發生了什麼?

This博客概述了究竟發生了什麼。

但是當我發佈到從屬節點會發生什麼?此節點是否會將首先發送消息的信息發送給主服務器?

該消息將被重定向到主隊列 - 也就是創建隊列的節點。

但是,您如何處理主故障?那麼其中一名奴隸將被選爲主人,所以你必須知道在哪裏連接?

同樣,這覆蓋了here。實質上,您需要一個單獨的服務來輪詢RabbitMQ並確定節點是否存在。 RabbitMQ爲此提供了一個management API。您的發佈和使用應用程序需要直接引用此服務,或者通過相互數據存儲來引用此服務,以確定要發佈或使用的正確節點。

與兔子的連接是永久的,所以如果它失敗了,你必須重新創建它。此外,你必須在這種情況下重新發送消息,否則你將失去它們。

您需要訂閱連接中斷事件才能對已斷開的連接作出反應。您需要在客戶端建立一定程度的冗餘,以確保消息不會丟失。如上所述,我建議您引入專門用於審問RabbitMQ的服務。客戶端可以嘗試將消息發佈到最後一次已知的活動連接,如果發生故障,客戶端可能會向監控服務器詢問RabbitMQ羣集的最新列表。假設至少有一個活動節點,客戶端然後可以建立到它的連接併成功發佈消息。

即使這一切,消息仍可能丟失,因爲它們可能是在運輸過程中,當我殺死一個節點

有,你不能與冗餘覆蓋某些邊緣的情況下, RabbitMQ也不是。例如,當消息落入隊列時,HA策略調用後臺進程將消息複製到備份節點。在此過程中,消息在被保存到備份節點之前可能會丟失。如果主動節點立即失敗,消息將會丟失。對此無能爲力。不幸的是,當我們降低到通過網絡傳輸的實際字節數時,我們可以構建的安全措施數量有限。

因此,消費者應用程序需要執行重複數據刪除或以冪等方式處理傳入消息。

您可以通過多種方式處理此問題。例如,將message-ttl設置爲相對較低的值將確保重複的郵件不會長時間保留在隊列中。您還可以使用唯一引用標記每條消息,並在消費者級別檢查該引用。當然,這需要存儲已處理消息的緩存以比較傳入的消息;其思想是如果先前處理的消息到達,其標籤將被消費者緩存,並且該消息可以被忽略。

我在AMQP和基於隊列的解決方案中強調的一件事是,您的基礎架構提供了工具,但不是整個解決方案。您必須根據您的業務需求彌補這些差距。通常,最好的解決方案是通過反覆試驗得出的。我希望我的建議有用。我在這裏發佈了許多RabbitMQ設計解決方案的博客,其中包括您提到的問題,如果您有興趣,請致電here

+1

謝謝保羅。你是上帝。只是爲了確保在執行之前能夠確認這一點:1)我仍然可以使用HAProxy並且發佈者確認,並且我不會丟失任何消息。我將有重複的消息,我必須以某種方式刪除。我會遇到性能問題(由於第一次到達從機時會額外跳躍到主機),但我的數據將是「防彈」的。 2)爲了提高性能,我將創建一個監視器服務,以便每次只將我的請求發送給主服務器,但我仍然需要處理重複的問題。謝謝。 – 2014-11-26 10:45:57

+1

您仍然可以使用HAProxy,但您會因循環配置而產生額外的網絡跳數。如果你想實現負載均衡,請閱讀下面的內容:http://insidethecpu.com/2014/11/17/load-balancing-a-rabbitmq-cluster/你將不會有重複的消息。我認爲設置message-ttl屬性足以刪除重複項,儘管如前所述添加參考標記可以解決問題。我將在C#中發佈一個RabbitMQ庫,可以很快實現上述所有功能。繼續監控我的博客的更新。 – 2014-11-26 11:06:19

+1

其實我最終有重複的消息。我跑了一次測試幾次發佈10000個消息到2節點兔子集羣。我殺了一個節點,我收到了10011-10012條消息。我的一個消費API是冪等的,所以最終的結果是好的。非常感謝。 – 2014-11-26 11:50:09