第一種:(生產(chǎn)者)生產(chǎn)者弄丟了數(shù)據(jù)。生產(chǎn)者將數(shù)據(jù)發(fā)送到 RabbitMQ 的時候,可能數(shù)據(jù)就在半路給搞丟了,因為網(wǎng)絡(luò)問題啥的,都有可能。
第二種:(服務(wù)端)RabbitMQ 弄丟了數(shù)據(jù)。MQ還沒有持久化自己掛了
第三種:(消費者)消費端弄丟了數(shù)據(jù)。剛消費到,還沒處理,結(jié)果進程掛了,比如重啟了。
?
1.針對生產(chǎn)者
方案2: 使用confirm機制
事務(wù)機制和 confirm 機制最大的不同在于,事務(wù)機制是同步的,你提交一個事務(wù)之后會阻塞在那兒,但是 confirm 機制是異步的
在生產(chǎn)者開啟了confirm模式之后,每次寫的消息都會分配一個唯一的id,然后如果寫入了rabbitmq之中,rabbitmq會給你回傳一個ack消息,告訴你這個消息發(fā)送OK了;如果rabbitmq沒能處理這個消息,會回調(diào)你一個nack接口,告訴你這個消息失敗了,你可以進行重試。而且你可以結(jié)合這個機制知道自己在內(nèi)存里維護每個消息的id,如果超過一定時間還沒接收到這個消息的回調(diào),那么你可以進行重發(fā)
2.針對RabbitMQ
有三點需要注意:
(1)要保證rabbitMQ不丟失消息,那么就需要開啟rabbitMQ的持久化機制,即把消息持久化到硬盤上,這樣即使rabbitMQ掛掉在重啟后仍然可以從硬盤讀取消息;
(2)如果rabbitMQ單點故障怎么辦,這種情況倒不會造成消息丟失,這里就要提到rabbitMQ的3種安裝模式,單機模式、普通集群模式、鏡像集群模式,這里要保證rabbitMQ的高可用就要配合HAPROXY做鏡像集群模式
(3)如果硬盤壞掉怎么保證消息不丟失
(1)消息持久化
RabbitMQ 的消息默認(rèn)存放在內(nèi)存上面,如果不特別聲明設(shè)置,消息不會持久化保存到硬盤上面的,如果節(jié)點重啟或者意外crash掉,消息就會丟失。所以就要對消息進行持久化處理。如何持久化,下面具體說明下:
? ? 要想做到消息持久化,必須滿足以下三個條件,缺一不可。
1) Exchange 設(shè)置持久化
2)Queue 設(shè)置持久化
3)Message持久化發(fā)送:發(fā)送消息設(shè)置發(fā)送模式deliveryMode=2,代表持久化消息
?
(2)設(shè)置集群鏡像模式
我們先來介紹下RabbitMQ三種部署模式:
1)單節(jié)點模式:最簡單的情況,非集群模式,節(jié)點掛了,消息就不能用了。業(yè)務(wù)可能癱瘓,只能等待。
2)普通模式:消息只會存在與當(dāng)前節(jié)點中,并不會同步到其他節(jié)點,當(dāng)前節(jié)點宕機,有影響的業(yè)務(wù)會癱瘓,只能等待節(jié)點恢復(fù)重啟可用(必須持久化消息情況下)。
3)鏡像模式:消息會同步到其他節(jié)點上,可以設(shè)置同步的節(jié)點個數(shù),但吞吐量會下降。屬于RabbitMQ的HA方案
(3)消息補償機制
為什么還要消息補償機制呢?難道消息還會丟失,沒錯,系統(tǒng)是在一個復(fù)雜的環(huán)境,不要想的太簡單了,雖然以上的三種方案,基本可以保證消息的高可用不丟失的問題,
比如:持久化的消息,保存到硬盤過程中,當(dāng)前隊列節(jié)點掛了,存儲節(jié)點硬盤又壞了,消息丟了,怎么辦?
1)生產(chǎn)端首先將業(yè)務(wù)數(shù)據(jù)以及消息數(shù)據(jù)入庫,需要在同一個事務(wù)中,消息數(shù)據(jù)入庫失敗,則整體回滾
2)根據(jù)消息表中消息狀態(tài),失敗則進行消息補償措施,重新發(fā)送消息處理。
3.針對消費者
方案一:ACK確認(rèn)機制
多個消費者同時收取消息,比如消息接收到一半的時候,一個消費者死掉了(邏輯復(fù)雜時間太長,超時了或者消費被停機或者網(wǎng)絡(luò)斷開鏈接),如何保證消息不丟?
使用rabbitmq提供的ack機制,服務(wù)端首先關(guān)閉rabbitmq的自動ack,然后每次在確保處理完這個消息之后,在代碼里手動調(diào)用ack。這樣就可以避免消息還沒有處理完就ack。才把消息從內(nèi)存刪除。
這樣就解決了,即使一個消費者出了問題,但不會同步消息給服務(wù)端,會有其他的消費端去消費,保證了消息不丟的case。
四、總結(jié)
?
?
如果需要保證消息在整條鏈路中不丟失,那就需要生產(chǎn)端、mq自身與消費端共同去保障。
生產(chǎn)端:對生產(chǎn)的消息進行狀態(tài)標(biāo)記,開啟confirm機制,依據(jù)mq的響應(yīng)來更新消息狀態(tài),使用定時任務(wù)重新投遞超時的消息,多次投遞失敗進行報警。
mq自身:開啟持久化,并在落盤后再進行ack。如果是鏡像部署模式,需要在同步到多個副本之后再進行ack。
消費端:開啟手動ack模式,在業(yè)務(wù)處理完成后再進行ack,并且需要保證冪等。
通過以上的處理,理論上不存在消息丟失的情況,但是系統(tǒng)的吞吐量以及性能有所下降。
在實際開發(fā)中,需要考慮消息丟失的影響程度,來做出對可靠性以及性能之間的權(quán)衡。文章來源:http://www.zghlxwxcb.cn/news/detail-711713.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-711713.html
到了這里,關(guān)于RabbitMQ消息丟失的場景,MQ消息丟失解決方案的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!