1. 程式人生 > 其它 >rabbitmq如何確保訊息不丟失 chengtian

rabbitmq如何確保訊息不丟失 chengtian

上篇寫了掌握Rabbitmq幾個重要概念,從一條訊息說起,這篇來總結關於訊息丟失讓人頭痛的事情。網路故障、伺服器重啟、硬碟損壞等都會導致訊息的丟失。訊息從生產到消費主要結果以下幾個階段如下圖。

①生產階段,生產者建立訊息,經過網路傳送到rabbit伺服器

②訊息儲存階段,首先被髮送到交換器然後經過路由演算法,到達佇列,等待被拉取消費

③消費階段,消費者經過網路從rabbit伺服器拉取訊息進行消費

這三個階段都有可能訊息丟失,下面一一分析。

訊息儲存階段

正常情況下,我們使用BasicPublish方法傳送訊息到交換器上然後路由到佇列上面,消費者還沒進行消費,此時伺服器重啟了(佇列、交換器使用預設的建立方式),會發生什麼?答案是:訊息丟失。原因很簡單:訊息在記憶體中,沒有刷盤,並且,他們預設是非持久化的,服務重啟之後,它們需要重新建立,訊息自然就丟失!

還好,Rabbit提供持久化的機制,佇列、交換器建立的時候,durable屬性設定為true,同時訊息投遞模式(delivery mode)設定為2,則訊息標記成持久化。這樣可以避免伺服器重啟訊息丟失的情況。

傳送階段

由於釋出操作不返回任何資訊給生產者,那你怎麼知道伺服器是否已經持久化了持久訊息到硬碟呢?伺服器可能在把訊息寫入磁碟前就宕機了,訊息因此而丟失!

有。)

Rabbit提供兩中解決方案,事務,但是效能會大打折扣,而且會使生產者應用程式產生同步。生產環境一般不會採用;另外一種方案是確認模式。也很簡單,訊息路由給所有匹配的訂閱佇列中,之後會非同步的告之生產者。使用channel.ConfirmSelect()方法,使通道開啟確認模式。然後注入兩個回撥函式,ack和nack事件。

channel.BasicAcks += (sender, ev) =>
                {
                    Console.WriteLine("訊息已經確認收到" + ev.DeliveryTag);

                };

                channel.BasicNacks += (sender, ev) =>
                {
                    Console.WriteLine("訊息未確認" + ev.DeliveryTag);
                };

消費階段

你可能會問,消費端訊息怎麼會丟失呢?Rabbitmq提供自動和手動確認訊息,然後訊息從佇列中移除。如果autoAck為true,自動確認模式,伺服器就會在訊息發給消費端後自動將其出隊。如果因為某些原因連線中斷了,或者你的消費端應用發生了故障,那麼訊息就會丟失!

通過把AutoAck設定為false,手工確認,告知伺服器,訊息已經處理了,可以進行訊息出隊刪除。

 channel.BasicConsume(queue: queueName,
                                     autoAck: false,
                                     consumer: consumer);
 consumer.Received += (model, ea) =>
                {
                    //dosometing
                    channel.BasicAck(ea.DeliveryTag, false);//確認
                };

小結:如果做了以上的處理,那麼訊息就不會跟你躲貓貓了。這裡有效能的問題,訊息持久化,是要刷到磁碟上的會影響投遞速度,並且訊息確認也會影響到訊息投遞速度。不基本上能夠滿足需求了。如果不能滿足效能需求,可以使用其他方法,比如 在每次

作者:阿笨

【官方QQ一群:跟著阿笨一起玩NET(已滿)】:422315558

【官方QQ二群:跟著阿笨一起玩C#(已滿)】:574187616

【官方QQ三群:跟著阿笨一起玩ASP.NET(已滿)】:967920586

【官方QQ四群:Asp.Net Core跨平臺技術開發(可加入)】:806491485

【官方QQ五群:.NET Core跨平臺開發技術(可加入)】:1036896405

【網易雲課堂】:https://study.163.com/provider/2544628/index.htm?share=2&shareId=2544628

【騰訊課堂】:https://abennet.ke.qq.com

【51CTO學院】:https://edu.51cto.com/sd/66c64

【微信公眾號】:http://dwz.cn/ABenNET