Java消息隊列之RabbitMQ消息可靠性

那些失敗的情況

網絡問題有很多原因出發失敗。防火牆也可能會中斷Idle連接,網絡失敗不是很快確定的。 硬件和軟件也會導致系統崩潰。客戶端軟件保持運行,而邏輯錯誤也可能會導致channel和connection錯誤。這就要求我們可以恢復new channel或者connection從這個問題中。

Java消息隊列之RabbitMQ消息可靠性

Connection 失敗

Connection失敗後,客戶端需要重新構建一個新的Connection。任何之前打開的Channel會重新打開。會有特定的異常拋出,例如Java 提供了ShutdownListener和DotNet提供的Iconnection.ConnectionShutdown時間。

Java消息隊列之RabbitMQ消息可靠性

確認和提交(Acknowledgements and Confirms)

當連接失敗,消息可能在客戶端和服務器端之間進行傳輸。 確認可以讓服務器和客戶端之間知道彼此的狀態。 在RabbitMQ中,Consumer與服務器之間確認行為叫做"Acknowledgements",而Producer與服務器之間確認行為叫做“Confirms”。

Acknowledgements的場景:消費軟件不確認這個消息,直到它使用接受到的消息,完成自己的工作。一旦Broker接受到這個消息確認信息,將清除這個消息。

Confirms的場景:當Broker接受到不能路由的消息,並且消息被設置為mandatory,消息basic.return會在basic.ack之前返回。對於路由之後的消息,basic.ack會讓所有接受到這個消息的數據,存儲到磁盤中。對於鏡像隊列來說(Mirrored Queue),會讓所有鏡像都統一確認這些消息。

Java消息隊列之RabbitMQ消息可靠性

心跳

部分網絡問題,包的丟失可能是由於操作系統破壞了TCP鏈接。AMQP使用心跳的特徵在軟件層次檢測鏈接是否被破壞了。心跳也會阻止一些網絡設備阻止當前“idle”tcp鏈接。 broker會協商連接的heartbeat的頻率。

Java消息隊列之RabbitMQ消息可靠性

對於Producer(消息生產者)

當使用confirm時候,如果channel或者connection失敗,Producer應該重新發送所有沒有來得及提交的數據。

這裡可能會造成數據重複,因為服務器broker可能已經發送確認數據到Producer了。因此consumer應用可以處理重複數據,保持一個冪等的狀態。(冪等狀態是指,無論consumer處理了幾次相同的數據,結果都是一樣的。例如:x=2是冪等。x=x+2就不是冪等)

Java消息隊列之RabbitMQ消息可靠性

確定消息是被路由的

producer應該保證發送的消息被路由(Router)到隊列中(Queues). 為了保證producer發送消息可以被最少一條隊列接受(Queue),我們在發送消息的時候,必須設置mandatory標示,在發送消息時候(AMQP的協議對應basic.publish,Java的版本對應Channel.basicPublish方法)。當消息沒有被隊列接受時,我們可以通過返回值(AMQP協議的basic.return)獲得一個返回碼和其他文本數據。

Producer也應該認識到發送消息到集群中,集群之間都需要複製消息。也增加了網絡失敗造成的延時情況。

Java消息隊列之RabbitMQ消息可靠性

對於Consumer(對於消費者)

如果一個消息發送到Consumer,而Consumer沒有確認並且Connection中斷,那麼這個消息重新進入隊列,再次發送出去之後,會有一個redelivedred標籤。幫助Consumer的應用判斷當前數據是否重複發送。

Consumer取消

Consumer取消是服務器端發起,告訴Consumer當前消費被終止了。Consumer取消發起的原因:當前的Queue被刪除,或者其他失敗情況。這是Rabbitmq的一個擴展,部分客戶端才能支持。(Java和DotNet都支持)。

Java消息隊列之RabbitMQ消息可靠性

消息不能被處理

consumer可以發送消息給服務端,告知消息被拒絕(AMQP的basic.reject和basic.nack),讓服務器重新發送他們,或者根據dead-letter參數參數。(dead-letter是配置Exchange和Queue時候配置的參數,我們可以進行相關的設置)。

分佈式下的RabbitMQ

當網絡不穩定的時候,使用federation和shovel來實現功能。我們也可以配置他們實現confirm和acknowledgement功能。

Java消息隊列之RabbitMQ消息可靠性


分享到:


相關文章: