rabbitmq 官方文件翻譯-2

weixin_33797791發表於2019-02-16

可靠性指南

什麼會導致失敗

網路問題可能是最常見的一類故障。
網路不僅可以發生故障,防火牆也可以中斷空閒連線,並且不會立即檢測到網路故障。
除連線故障外,代理和客戶端應用程式可能隨時遇到硬體故障(或軟體崩潰)。
此外,即使客戶端應用程式繼續執行,邏輯錯誤也可能導致通道或連線錯誤,從而迫使客戶端建立新的通道或連線並從問題中恢復。

連線失敗

如果連線失敗,客戶端將需要與代理建立新連線。
在先前連線上開啟的任何頻道都將自動關閉,這些頻道也需要重新開啟。
通常,當連線失敗時,客戶端將通過連線丟擲異常(或類似的語言構造)來通知客戶端。
官方Java和.NET客戶端還提供回撥方法,讓您瞭解其他上下文中的連線失敗 - Java在Connection類和Channel類上提供ShutdownListener回撥,同樣的目的,.NET客戶端為其提供IConnection.ConnectionShutdown和IModel.ModelShutdown事件

Acknowledgements and Confirms

當連線失敗時,訊息可能在客戶端和伺服器之間傳輸 - 它們可能正在被解析或生成,在OS緩衝區中或線上路上。
傳輸中的郵件將丟失 - 需要重新傳輸。
Acknowledgements讓伺服器和客戶知道何時執行此操作。
Acknowledgements可以在兩個方向上使用 - 允許消費者向伺服器指示它已經接收/處理了訊息並允許伺服器向生產者指示相同的東西。RabbitMQ將後一種情況稱為“ confirm”。

當然,TCP確保已收到資料包,並將重新傳輸直到它們 - 但這只是網路層。
Acknowledgements和Confirms表明已收到訊息並採取行動。
acknowledgement訊號表示收到訊息,以及所有權轉移,接收方承擔全部責任的。

因此,Acknowledgements具有語義 - 消費應用程式在完成對它們所需的任何操作之前不應該確認訊息 - 將它們記錄在資料庫中,轉發它們,將它們列印到紙上或其他任何東西上。一旦這樣做,代理可以自由地忘記該訊息。

類似的,代理一旦承擔責任就會確認訊息。Acknowledgements的使用保證至少一次交付。如果沒有確認,則在釋出和使用操作期間可能會丟失郵件,並且只保證最多一次交付。

使用心跳檢測已死的TCP連線

在某些型別的網路故障中,資料包丟失可能意味著中斷的TCP連線需要相當長的時間(例如,在Linux上使用預設配置,大約需要11分鐘)才能被作業系統檢測到。AMQP 0-9-1提供心跳功能,以確保應用程式層及時發現中斷的連線(以及完全沒有響應的對端)。心跳還可以防禦可能終止“空閒”TCP連線的某些網路裝置。

代理

為了避免在代理中丟失訊息,我們需要應對代理重啟,代理硬體故障以及極端甚至代理崩潰。
為確保訊息和代理定義在重新啟動後仍然存在,我們需要確保它們位於磁碟上。
AMQP標準具有exchange,佇列和持久訊息的永續性概念,要求持久物件或持久訊息在重新啟動後仍然存在。

叢集和高可用性

如果我們需要確保我們的代理從硬體故障中存活,我們可以使用RabbitMQ的叢集。
在RabbitMQ叢集中,所有定義(exchange,繫結,使用者等)都在整個叢集中進行映象。
佇列的行為方式不同,預設情況下僅駐留在單個節點上,但可選擇跨多個或所有節點進行映象。無論位於何處,佇列都可以從所有節點看到並可訪問。

映象佇列在所有已配置的叢集節點上覆制其內容,無縫地容忍節點故障並且不會丟失訊息.但是,消費應用程式需要注意,當佇列失敗時,他們的消費者將被取消,他們將需要重新構建

生產者

使用確認時,從通道或連線失敗中恢復的生產者應重新傳輸尚未從代理收到確認的任何訊息。
此處存在訊息重複的可能性,因為代理可能已傳送了從未到達生產者的確認(由於網路故障等)。
因此,消費者應用程式將需要以冪等方式執行重複資料刪除或處理傳入訊息。

確保訊息被路由

在某些情況下,生產者必須確保他們的訊息被路由到佇列(儘管並非總是如此 - 在pub-sub系統的情況下,生產者只會釋出,如果沒有消費者感興趣,那麼訊息丟棄是正確的)。
為確保將訊息路由到單個已知佇列,生產者只需宣告目標佇列並直接釋出到該佇列即可。如果訊息可能以更復雜的方式路由,但生產者仍然需要知道他們是否至少到達一個佇列,它可以在basic.publish上設定mandatory標誌,如果沒有適當的繫結佇列 確保basic.return(包含回覆程式碼和一些文字)將被髮送回客戶端。

生產者還應該意識到,當釋出到叢集節點時,如果繫結到exchange的一個或多個目標佇列在叢集中具有映象,則由於流之間的流量控制,由於副本和主佇列程式之間的流量控制,可能會在節點之間的網路故障面臨時出現延遲.

消費者

在網路出現故障(或節點崩潰)的情況下,可以複製訊息,並且消費者必須準備好處理它們。
如果可能,處理此問題的最簡單方法是確保您的消費者以冪等方式處理訊息,而不是明確處理重複資料刪除。
如果訊息被傳遞給消費者然後重新排隊(例如,因為它在消費者連線丟失之前沒有得到確認),那麼RabbitMQ將在再次傳遞時為其設定redelivered的標誌(無論是同一個消費者還是另一個消費者))。
這是一個消費者之前可能已經看到此訊息的暗示(儘管不能保證,訊息可能已經從代理中刪除但在連線丟失之前沒有進入消費者)。
相反,如果未設定redelivered的標誌,則保證之前沒有看到該訊息。因此,如果消費者發現重複刪除訊息或以冪等方式處理訊息更加昂貴,可以通過設定了redelivered標誌的訊息執行此操作。

消費者取消通知

在某些情況下,伺服器需要能夠取消消費者 - 因為它正在消耗的佇列已被刪除或已經故障轉移。
在這種情況下,消費者應該再次消費,但要注意它可能再次看到它已經看到的訊息。
請注意,消費者取消通知是AMQP的RabbitMQ擴充套件,因此可能並非所有客戶端都支援

無法處理的訊息

如果消費者確定它無法處理訊息,那麼它可以使用basic.reject(或basic.nack)拒絕它,要麼伺服器重新排隊或者不(在這種情況下伺服器可能配置為死信)

分散式RabbitMQ

Rabbit提供了兩個外掛來協助在不可靠的網路上分配節點:federation和shovel。
兩者都是作為AMQP客戶端實現的,因此如果將它們配置為使用confirms 和 acknowledgements,它們將在必要時重新傳輸。兩者都預設使用confirms 和 acknowledgements。
當使用federation和shovel連線叢集時,希望確保federation 連結和shovel容忍節點故障。
federation將自動在下游群集中分發連結,並在下游節點發生故障時將其故障轉移。
為了在上游節點發生故障時連線到新的上游,您可以為上游指定多個冗餘URI,或者通過TCP負載平衡器進行連線。
使用shovel時,可以在源或目標clause中指定冗餘代理;但是目前還不可能使shovel本身冗餘。我們希望將來改善這種狀況;同時,如果新節點最初執行的節點出現故障,則可以手動啟動新節點以執行shovel。

相關文章