日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

RabbitMq如何确保消息不丢失

發(fā)布時間:2023/12/4 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 RabbitMq如何确保消息不丢失 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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

①生產階段,生產者創(chuàng)建消息,經過網絡發(fā)送到rabbit服務器

②消息存儲階段,首先被發(fā)送到交換器然后經過路由算法,到達隊列,等待被拉取消費

③消費階段,消費者經過網絡從rabbit服務器拉取消息進行消費?

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

消息存儲階段

正常情況下,我們使用BasicPublish方法發(fā)送消息到交換器上然后路由到隊列上面,消費者還沒進行消費,此時服務器重啟了(隊列、交換器使用默認的創(chuàng)建方式),會發(fā)生什么?答案是:消息丟失。原因很簡單:消息在內存中,沒有刷盤,并且,他們默認是非持久化的,服務重啟之后,它們需要重新創(chuàng)建,消息自然就丟失!

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

發(fā)送階段

由于發(fā)布操作不返回任何信息給生產者,那你怎么知道服務器是否已經持久化了持久消息到硬盤呢?服務器可能在把消息寫入磁盤前就宕機了,消息因此而丟失!

?有。)

Rabbit提供兩中解決方案,事務,但是性能會大打折扣,而且會使生產者應用程序產生同步。生產環(huán)境一般不會采用;另外一種方案是確認模式。也很簡單,消息路由給所有匹配的訂閱隊列中,之后會異步的告之生產者。使用channel.ConfirmSelect()方法,使信道開啟確認模式。然后注入兩個回調函數,ack和nack事件。

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

消費階段

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

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

?

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

小結:如果做了以上的處理,那么消息就不會跟你躲貓貓了。這里有性能的問題,消息持久化,是要刷到磁盤上的會影響投遞速度,并且消息確認也會影響到消息投遞速度。不基本上能夠滿足需求了。如果不能滿足性能需求,可以使用其他方法,比如 在每次發(fā)送消息的時候,都包含應答隊列的名稱,這樣消費者就可以回發(fā)應答以確認接受到了。如果消息應答未在合理時間范圍內到達,生產者就重新發(fā)送消息。

總結

以上是生活随笔為你收集整理的RabbitMq如何确保消息不丢失的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。