溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

RabbitMq怎么確保消息不丟失

發(fā)布時(shí)間:2021-08-30 21:07:53 來(lái)源:億速云 閱讀:274 作者:chen 欄目:大數(shù)據(jù)

本篇內(nèi)容主要講解“RabbitMq怎么確保消息不丟失”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“RabbitMq怎么確保消息不丟失”吧!


①生產(chǎn)階段,生產(chǎn)者創(chuàng)建消息,經(jīng)過(guò)網(wǎng)絡(luò)發(fā)送到rabbit服務(wù)器

②消息存儲(chǔ)階段,首先被發(fā)送到交換器然后經(jīng)過(guò)路由算法,到達(dá)隊(duì)列,等待被拉取消費(fèi)

③消費(fèi)階段,消費(fèi)者經(jīng)過(guò)網(wǎng)絡(luò)從rabbit服務(wù)器拉取消息進(jìn)行消費(fèi) 

RabbitMq怎么確保消息不丟失


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

消息存儲(chǔ)階段

正常情況下,我們使用   BasicPublish   方法發(fā)送消息到交換器上然后路由到隊(duì)列上面,消費(fèi)者還沒(méi)進(jìn)行消費(fèi),此時(shí)服務(wù)器重啟了(隊(duì)列、交換器使用默認(rèn)的創(chuàng)建方式),會(huì)發(fā)生什么?答案是:消息丟失。原因很簡(jiǎn)單:消息在內(nèi)存中,沒(méi)有刷盤(pán),并且,他們默認(rèn)是非持久化的,服務(wù)重啟之后,它們需要重新創(chuàng)建,消息自然就丟失!  
還好,Rabbit提供持久化的機(jī)制,隊(duì)列、交換器創(chuàng)建的時(shí)候,   durable   屬性設(shè)置為true,同時(shí)消息投遞模式(   delivery mode   )設(shè)置為2,則消息標(biāo)記成持久化。這樣可以避免服務(wù)器重啟消息丟失的情況。  

RabbitMq怎么確保消息不丟失

發(fā)送階段

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

 有。)

Rabbit提供兩中解決方案,   事務(wù)   ,但是性能會(huì)大打折扣,而且會(huì)使生產(chǎn)者應(yīng)用程序產(chǎn)生同步。生產(chǎn)環(huán)境一般不會(huì)采用;另外一種方案是   確認(rèn)模式   。也很簡(jiǎn)單,消息路由給所有匹配的訂閱隊(duì)列中,之后會(huì)異步的告之生產(chǎn)者。使用channel.ConfirmSelect()方法,使信道開(kāi)啟確認(rèn)模式。然后注入兩個(gè)回調(diào)函數(shù),ack和nack事件。  
channel.BasicAcks += (sender, ev) =>                {                    Console.WriteLine("消息已經(jīng)確認(rèn)收到" + ev.DeliveryTag);
               };
               channel.BasicNacks += (sender, ev) =>                {                    Console.WriteLine("消息未確認(rèn)" + ev.DeliveryTag);                };
 


消費(fèi)階段

你可能會(huì)問(wèn),消費(fèi)端消息怎么會(huì)丟失呢?Rabbitmq提供自動(dòng)和手動(dòng)確認(rèn)消息,然后消息從隊(duì)列中移除。如果   autoAck   為true,自動(dòng)確認(rèn)模式,服務(wù)器就會(huì)在消息發(fā)給消費(fèi)端后自動(dòng)將其出隊(duì)。如果因?yàn)槟承┰蜻B接中斷了,或者你的消費(fèi)端應(yīng)用發(fā)生了故障,那么消息就會(huì)丟失!  

通過(guò)把AutoAck設(shè)置為false,手工確認(rèn),告知服務(wù)器,消息已經(jīng)處理了,可以進(jìn)行消息出隊(duì)刪除。

 

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

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

到此,相信大家對(duì)“RabbitMq怎么確保消息不丟失”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI