【RabbitMQ doc】可靠性指南

可靠性指南

本頁面介紹如何使用AMQP和RabbitMQ的特性來達到可靠性傳輸——確保消息即便遇到失敗的狀況下也可以發送。html

什麼狀況下會失敗?

網絡問題多是最多見的失敗狀況。除了網絡失敗,防火牆還會中斷空閒鏈接,並且網絡失敗不必定可以like檢測獲得。node

除了鏈接性失敗,broker和client應用可能會遇到硬件失敗(或者軟件崩潰)。即便是客戶端應用一直在運行,邏輯錯誤也可能致使通道或者鏈接錯誤,這會強制客戶端從新創建通道或者鏈接來恢復問題。linux

鏈接失敗

對於網絡鏈接失敗,客戶端會創建新的鏈接。以前鏈接上的通道會被自動關閉,而後在從新打開。數據庫

一般狀況,遇到網絡鏈接失敗,鏈接會拋出異常來通知客戶端。官方的Java和.NET客戶端會提供額外的callback方法,讓你接收鏈接失敗的消息。【省略……】緩存

應答和確認

消息在客戶端和服務端之間傳輸時可能會遇到鏈接失敗——它們可能正在系統緩存或者線路上被解析或者生成。傳輸中的消息須要被重傳。應答(acknowledgement)讓服務端和客戶端知道何時重傳。網絡

acknowledgement能夠雙向應用——容許consumer向server說明它已收到/處理了一條消息,也容許producer作一樣的事情。RabbitMQ將後一種狀況叫作confirm(確認)負載均衡

TCP爲了確保數據包能被收到,會進行重傳——這只是針對網絡層。應答和確認代表消息已被收到而且被正確處理。應答消息既代表收到了消息,也代表了消息的全部者發生了轉移。分佈式

acknowledgements所以具備以下意義——消費者應用只有在完成它應作的工做後才進行應答,好比記錄進數據庫,轉發、打印到文件或任何其餘地方。完成該操做後,broker能夠釋放掉該消息。ide

相似,broker只有在接管了消息以後纔會進行確認。ui

應答保證消息至少有一次被送達。沒有應答可能會致使消息在消息發佈、消費操做時丟失,而且只能保證之多有一次被送達。

使用心跳檢測失效TCP鏈接

在特殊的網絡失敗中,檢測到TCP鏈接的失敗須要至關長的時間(linux默認時間大約11分鐘)。AMQP 0-9-1提供了心跳檢測機制確保應用層能夠發現中斷的鏈接(也包括徹底無響應的對端)。心跳檢測還能夠確保空閒鏈接不被中斷。

 

Broker端(代理人)

爲了不消息丟失,須要處理broker的重啓、broker的硬件故障、甚至極端狀況下的broker崩潰。

爲了確保消息和broker的屬性在重啓後仍然存在,須要將其寫入磁盤。AMQP標準中有exchanges、queues的持久化概念,保證重啓以後消息仍然存在。更多細節參見AMQP Concepts Guide

集羣和高可用

若是要保證broker在重啓後仍然存在,咱們可使用RabbitMQ的集羣功能。集羣中,全部定義(exchanges、bindings、users等等)在整個集羣中鏡像存在。隊列請求默認只存在於單個節點,但能夠根據狀況鏡像到某些甚至全部節點。隊列請求對於全部節點都是可見可達的。

鏡像隊列將消息內容複製到整個配置好的集羣節點上,容忍節點失效且無消息丟失。不過消費應用程序須要注意當隊列出現問題後,consumer會被取消,以後他們會被從新消費。

 

Producer端

在須要confirm的狀況下,從通道或鏈接失效中恢復的producer須要從新發送未接收到來自於broker的acknowledgements的消息。這可能存在消息重複,由於broker可能已經發送了confirm消息但producer沒有收到。所以消費者應用須要去重,或者以冪等方式處理進入的消息。

確保消息已被路由

特定環境下,對於producer來講,須要確保消息已被路由到隊列中(並不老是如此,在pub-sub發佈訂閱系統中,生產者只發布消息,若是沒有消費者消費,消息將被丟棄)。

爲了確保消息被路由到單個隊列,消費者會聲明目的隊列,並直接發佈給隊列。若是消息須要以更復雜的方式路由,producer仍然須要確保消息至少路由到一個隊列,能夠設置basic.publish的強制標記,確保沒有queues綁定的狀況下,basic.return(包含回覆代碼以及一些文本說明)送回到客戶端。

producer須要注意,向集羣發佈時,若是一個或多個目的隊列有鏡像存在,因爲網絡錯誤的緣由,可能會致使延遲發生。

消費者

在網絡失敗狀況下,消息可能會出現重複,消費者須要準備好處理它。可能狀況下,最簡單的方式是保證消費者以冪等方式處理消息,而不是去重。

若是某個消息發送達到消費者以後,重傳給隊列,RabbitMQ會設置重傳標記。這代表消費者可能以前接收過該消息。與之對應的是,若是重傳標記未設置,這能夠保證消息是第一次被接收。所以,若是消息以冪等方式或去重方式處理比較困難,能夠只處理帶有重傳標記的消息集合。

Consumer Cancel Notification

Under some circumstances the server needs to be able to cancel a consumer - since the queue it was consuming from has been deleted, or has failed over. In this case the consumer should consume again but be aware that it may see messages again which it has already seen.

Note that consumer cancel notification is a RabbitMQ extension to AMQP, and as such may not be supported by all clients.

 

Messages That Cannot Be Processed

If a consumer determines that it cannot handle a message then it can reject it using basic.reject (orbasic.nack), either asking the server to requeue it, or not (in which case the server might be configured todead-letter it instead.

 

分佈式RabbitMQ

Rabbit 提供了兩種分佈式節點應對不可靠網絡:federation和shovel。兩種方式都採用了AMQP客戶端方式,若是你配置(默認便是)了確認和應答,他們在特定狀況下會進行消息重傳。

當使用federation或shovel鏈接到集羣,須要容忍節點失效。下游節點失效時,federation會自動分佈鏈接到下游的集羣。當上遊節點失效時,爲了鏈接到新的上游節點,你能夠爲一個upstream指定多個備用URIs,或者使用TCP負載均衡。

When using the shovel, it is possible to specify redundant brokers in a source or destination clause; however it is not currently possible to make the shovel itself redundant. We hope to improve this situation in the future; in the mean time a new node can be brought up manually to run a shovel if the node it was originally running on fails.

https://www.rabbitmq.com/reliability.html

相關文章
相關標籤/搜索