Rabbitmq如何保證不丟消息

背景介紹:

筆者最近研究了下rabbitmq,便很好奇它是怎麼保證不丟失消息的呢?於是便整理了這篇文章來跟大家分享下,自己的理解,如有不準確的地方或者不同的意見,還請各位能夠給出反饋,我們可以討論,相互學習,相互成長。

基礎知識:

在開始探討這個問題之前,筆者還是覺得很有必要將rabbitmq的架構等基礎知識回顧下,如下所示:

對於使用rabbitmq的服務來說,主要由三部分構成,它們分別是:生產者,rabbitmq,消費者。這三者之間是通過網絡來進行通訊的,其中與生產者對應的是exchange,與消費者對應的是connection,而rabbitmq內部又由exchange,queue,connection三部分構成。

消息的流程:消息是由生產者生產了之後,上報給exchange,exchange綁定並存儲到queue中,再傳遞給最終的消費者手裏。

如此以來,整個過程就分成了三大場景:

場景1: 生產者與exchange的上報消息,如何保證不丟失?

對於網絡通訊來說,解決丟數據最好的辦法就是,消息確認機制,而rabbitmq裏面是通過兩個方式來保證:一種是事務機制,這個是在amqp協議層面保證的,具體操作如下所示:

RabbitMQ中與事務機制有關的方法有三個:txSelect(), txCommit()以及txRollback(), txSelect用於將當前channel設置成transaction模式,txCommit用於提交事務,txRollback用於回滾事務,在通過txSelect開啓事務之後,我們便可以發佈消息給broker代理服務器了,如果txCommit提交成功了,則消息一定到達了broker了,如果在txCommit執行之前broker異常崩潰或者由於其他原因拋出異常,這個時候我們便可以捕獲異常通過txRollback回滾事務了。(備註:採用事務機制實現會降低RabbitMQ的消息吞吐量。)

步驟爲:

1.client----發送----->Tx.Select

2.broker----發送----->Tx.Select-Ok(之後publish)

3.client------發送----->Tx.Commit

4.broker------發送---->Tx.Commit-Ok

一種是confrim機制:

原理:消息響應機制,

生產者將信道設置成confirm模式,一旦信道進入confirm模式,所有在該信道上面發佈的消息都會被指派一個唯一的ID(從1開始),一旦消息被投遞到所有匹配的隊列之後,broker就會發送一個確認給生產者(包含消息的唯一ID),這就使得生產者知道消息已經正確到達目的隊列了,如果消息和隊列是可持久化的,那麼確認消息會將消息寫入磁盤之後發出,broker回傳給生產者的確認消息中deliver-tag域包含了確認消息的序列號。

confrim的優勢是,它是異步的,在生產者發送完一個消息之後,不必要等這個消息的返回,就可以繼續處理另外一個消息,等待消息的ack返回之後,再去處理前面發過的消息,類似於多路複用的做法。rabbitmq在收到之後,會回覆ack,如果因爲rabbitmq自身的問題導致的,會回覆nack消息。

對於生產者來說,爲了方便確認消息有沒有真正到達rabbitmq端,還需要在生產者端設置超時重發,畢竟網絡裏面是可能丟失消息的。

confrim方式使用的API:

https://godoc.org/github.com/streadway/amqp#Channel.Confirm

場景2: 消費者從queue中獲取消息如何保證不丟失?

........

詳細參考:灰子學技術 :Rabbitmq如何保證不丟消息


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章