RabbitMQ如何防止訊息丟失及重複消費

2022-10-08 19:48:16 字數 2355 閱讀 7419

一、rabbitmq出現訊息丟失的情況及其解決辦法

如圖所示,rabbitmq丟失訊息的情況可以傳送在任何乙個節點。

a、丟失的原因:因為網路傳輸的不穩定性,當生產者在向mq傳送訊息的過程中,mq沒有成功接收到訊息,但是生產者卻以為mq成功接收到了訊息,不會再次重**送該訊息,從而導致訊息的丟失。

b、解決辦法: 有兩個解決辦法:事務機制和confirm機制,最常用的是confirm機制。

事務機制:

rabbitmq 提供了事務功能,生產者傳送資料之前開啟 rabbitmq 事務channel.txselect,然後傳送訊息,如果訊息沒有成功被 rabbitmq 接收到,那麼生產者會收到異常報錯,此時就可以回滾事務channel.txrollback,然後重試傳送訊息;如果收到了訊息,那麼可以提交事務channel.txcommit。偽**如下:

// 開啟事務

channel.txselect

try  catch (exception e)

// 提交事務

channel.txcommit

confirm機制:

rabbitmq可以開啟confirm模式,在生產者那裡設定開啟confirm模式之後,生產者每次寫的訊息都會分配乙個唯一的 id,如果訊息成功寫入 rabbitmq 中,rabbitmq 會給生產者回傳乙個ack訊息,告訴你說這個訊息 ok 了。如果 rabbitmq 沒能處理這個訊息,會**你的乙個nack介面,告訴你這個訊息接收失敗,生產者可以傳送。而且你可以結合這個機制自己在記憶體裡維護每個訊息 id 的狀態,如果超過一定時間還沒接收到這個訊息的**,那麼可以重發。

注意:rabbitmq的事務機制是同步的,很耗型能,會降低rabbitmq的吞吐量。confirm機制是非同步的,生成者傳送完乙個訊息之後,不需要等待rabbitmq的**,就可以傳送下乙個訊息,當rabbitmq成功接收到訊息之後會自動非同步的**生產者的乙個介面返回成功與否的訊息。

a、丟失的原因:rabbitmq接收到生產者傳送過來的訊息,是存在記憶體中的,如果沒有被消費完,此時rabbitmq宕機了,那麼再次啟動的時候,原來記憶體中的那些訊息都丟失了。

b、解決辦法:開啟rabbitmq的持久化。當生產者把訊息成功寫入rabbitmq之後,rabbitmq就把訊息持久化到磁碟。結合上面的說到的confirm機制,只有當訊息成功持久化磁碟之後,才會**生產者的介面返回ack訊息,否則都算失敗,生產者會重新傳送。存入磁碟的訊息不會丟失,就算rabbitmq掛掉了,重啟之後,他會讀取磁碟中的訊息,不會導致訊息的丟失。

c、持久化的配置:

注意:持久化要起作用必須同時設定這兩個持久化才行,rabbitmq 哪怕是掛了,再次重啟,也會從磁碟上重啟恢復 queue,恢復這個 queue 裡的資料。

a、丟失的原因:如果rabbitmq成功的把訊息傳送給了消費者,那麼rabbitmq的ack機制會自動的返回成功,表明傳送訊息成功,下次就不會傳送這個訊息。但如果就在此時,消費者還沒處理完該訊息,然後宕機了,那麼這個訊息就丟失了。

b、解決的辦法:簡單來說,就是必須關閉 rabbitmq 的自動ack,可以通過乙個 api 來呼叫就行,然後每次在自己**裡確保處理完的時候,再在程式裡ack一把。這樣的話,如果你還沒處理完,不就沒有ack了?那 rabbitmq 就認為你還沒處理完,這個時候 rabbitmq 會把這個消費分配給別的 consumer 去處理,訊息是不會丟的。

先說為什麼會重複消費:正常情況下,消費者在消費訊息的時候,消費完畢後,會傳送乙個確認訊息給訊息佇列,訊息佇列就知道該訊息被消費了,就會將該訊息從訊息佇列中刪除;但是因為網路傳輸等等故障,確認資訊沒有傳送到訊息佇列,導致訊息佇列不知道自己已經消費過該訊息了,再次將訊息分發給其他的消費者。

解決思路是:保證訊息的唯一性,就算是多次傳輸,不要讓訊息的多次消費帶來影響;保證訊息等冪性;

這個問題針對業務場景來答分以下幾點:

如果訊息是做資料庫的insert操作,給這個訊息做乙個唯一主鍵,那麼就算出現重複消費的情況,就會導致主鍵衝突,避免資料庫出現髒資料。

如果訊息是做redis的set的操作,不用解決,因為無論set幾次結果都是一樣的,set操作本來就算冪等操作。

如果以上兩種情況還不行,可以準備乙個第三方介質,來做消費記錄。以redis為例,給訊息分配乙個全域性id,只要消費過該訊息,將以k-v形式寫入redis。那消費者開始消費前,先去redis中查詢有沒

RabbitMQ防止訊息丟失

rabbitmq中,訊息丟失可以簡單的分為兩種 客戶端丟失和服務端丟失。針對這兩種訊息丟失,rabbitmq都給出了相應的解決方案。回到目錄 如圖,生產者p向佇列中生產訊息,c1和c2消費佇列中的訊息,預設情況下,rabbitmq會平均的分發消費給c1c2 round robin dispatchi...

RabbitMQ防止訊息丟失

rabbitmq一般情況很少丟失,但是不能排除意外,為了保證系統高可用,我們必須作出更好完善措施,保證系統的穩定性。1.訊息持久化 2.ack確認機制 3.設定集群映象模式 4.訊息補償機制 第一種 訊息持久化 rabbitmq 的訊息預設存放在記憶體上面,如果不特別宣告設定,訊息不會持久化儲存到硬...

RabbitMQ如何防止資料丟失

解決方案 rabbitmq提供了transaction和cofirm模式來確保生產者不丟訊息.tansaction機制就是說 解決方案 處理訊息佇列丟失的情況,一般是開啟持久化磁碟的配置,將durable設定為true bean public exchange orderseckillexchang...