【Message Queue - RabbitMQ】 如何保證消息可靠性?

閱讀時間約 4 分鐘

訊息傳遞的過程中有三種可能遺失的情境:

Producer端送到RabbitMQ時丟失:

  1. 外界環境問題導致: 發生網路丟包、網路故障等造成訊息丟失。
  2. 程式碼層面、配置層面導致訊息丟失。

RabbitMQ儲存的訊息丟失:

  1. 訊息沒有持久化。
  2. 磁碟意外損壞導致訊息同步失敗。

RabbitMQ送到Consumer時丟失:

消費者接收訊息後還沒來得及處理就當機。

處理方式:

為了確保訊息正確的送達RabbitMQ及Consumer正確的收到訊息,RabbitMQ為我們提供了兩種方式:
  1. 透過AMQP Transaction機制實現。
  2. 將Channel設定為confirm模式。

AMQP Transaction機制

主要有三個方法分別為:
  • txSelect(): 將當前的channel設定為transaction模式。
  • txCommit(): 提交事務。
  • txRollback(): 回滾事務。
可以看到下面流程中多了四個步驟,如此一來當資料量大的時候處理起來會比較沒有效率,因此一般應用狀況下很少採用Transaction機制。
try {
channel.txSelect();
channel.basicPublish(...);
channel.txCommit();
} catch (e) {
channel.txRollback();
}

Confirm模式 — 生產端

首先我們一樣將通道設定為Confirm模式,Confirm模式與AMQP Transaction機制只能選一個使用。
channel.confirmSelect();
Confirm模式又分為以下三種方式:
1. 普通Confirm模式: 每發送一條消息就等待服務端回應一次。
這種方式較沒效率,每次丟一個訊息就得等待通知。
try {
// 發送一條訊息
channel.basicPublish(...);
// 等待確認訊號
if(channel.waitForConfirms()){
// 發送成功
} else {
// 重送或其他處置
}
} catch(...) {
...
}
2. 批次Confirm模式: 發送一批消息後再等待服務端回應。
這種方式可以發送一批後再等待通知,乍看之下蠻有效率的,但如果訊息常常丟失,那麼我們也得批次重傳。
try {
// 發送多條訊息
for (i = 0; i < batchSize; i++) {
channel.basicPublish(...);
}
// 等待確認訊號
if(channel.waitForConfirms()){
// 發送成功
} else {
// 重送或其他處置
}
} catch(...) {
...
}
3. 異步Confirm模式: 以Listener方式等待服務端回應。
這邊以Listener的方式來獲取通知訊息,RabbitMQ會發送以下兩種通知:
  • Ack: 成功將訊息送到Queue。
  • Nack: Queue達到上限、MQ異常、磁碟寫滿…等造成未正確將訊息送到Queue。
這邊會有一種狀況是Ack、Nack都沒收到,如網路瞬斷…等,這時候就得搭配其他機制去進行重送。
try {
// 開啟Confirm模式
channel.confirmSelect();
channel.addConfirmListener(new ConfirmListener() {
public void handleAck(long deliveryTag, boolean multiple) throws IOException {
// 成功將訊息送到Queue。
}
public void handleNack(long deliveryTag, boolean multiple) throws IOException {
// Queue達到上限、MQ異常、磁碟寫滿...等。
}
});
} catch(...) {
...
}
以上都不保證100%投送到MQ,只是盡量的保證能夠送達而已,如果對於投送訊息的部份有強烈需求則可以考慮搭配Redis…等DB來維持是否送達的狀態,但勢必會捨棄一些效能。

Confirm模式 — 消費端

消費端的部份就相對單純,處理完訊息後發送ack確認訊號給RabbitMQ即可,RabbitMQ收到後就認為已經消費完成會將該訊息刪除。
為什麼會看到廣告
94會員
268內容數
哈囉,我是阿Han,是一位 👩‍💻 軟體研發工程師,喜歡閱讀、學習、撰寫文章及教學,擅長以圖代文,化繁為簡,除了幫助自己釐清思路之外,也希望藉由圖解的方式幫助大家共同學習,甚至手把手帶您設計出高品質的軟體產品。
留言0
查看全部
發表第一個留言支持創作者!
你可能也想看
清邁必做的101件事『Massage』超推這間老師級按摩小店!來到泰國一定要做的一件事絕對是按摩! 這家 Lar thai massage 不在清邁古城,也不在尼曼路,店址位於當地安安靜靜的居民區,雖然沒有高檔大氣的裝修,走的是溫馨家庭式路線。原本我已經連按了好幾天按摩,高檔跟便宜都有,可是肩背還是覺得很僵硬,來這裏按一次整個就鬆了很多。
Thumbnail
avatar
Ms.Xiao蕭小姐
2024-02-29
《Compassion》The sorrow of trees - a message from nature"You live for yourselves, not for humans." About trees and their feelings of sadness due to human interference.
Thumbnail
avatar
靈魂共感療域 EmpathyCave
2023-11-12
泰国曼谷-Aurora-Massageaurora是一家日式的情色按摩店,比一般的按摩店多出来的服务可能也就数气垫床服务了,妹子脱光了用大胸在你身上来回蹭的感觉,那种软软绵绵的感觉,让你既放松又血脉膨胀,确实是一般按摩效果无法达到的。
Thumbnail
avatar
whitehat.快乐在泰国
2023-10-30
曼谷的Wonder Massage什么是泰国的Massage?分两种,一种是常规的泰式足疗或者泰式按摩,价格便宜服务号。另一种是Body to Body Massage,也叫B2B Massage,当然,是由漂亮妹子给你全程服务的。价格比中国大陆的一线城市(北上广深杭)便宜多了,服务还更好,一对比下来,在国内找服务
Thumbnail
avatar
whitehat.快乐在泰国
2023-10-21
Unity Input System #2 | Send Messages & InputValue這篇文章將會講述如何使用程式腳本讀取 Input System 的玩家輸入。
Thumbnail
avatar
瓶裝雪
2023-07-17
Message to the Christian ChurchesAsk more, not less, of those you are inviting. Ask more of them than anyone ever has. Remind them who they are and help them become that.
Thumbnail
avatar
陳易宏
2022-11-22
Message from B'z【短文翻譯/B'z】收到了來自於本日8/10發行ALBUM「Highway X」的B'z的訊息☆ https://bz-vermillion.com/news/220512.html #Bz #HighwayX #LIVEGYM2022 #PresentX **********
Thumbnail
avatar
B'z Only
2022-08-10
【生命之樹│Massage】命名:緣起緩慢生命之樹想傳達的是一種身心靈保養理念,一種讓能量生生不息的四兩撥千斤,期許著每一位客戶在課程結束之後,身心都能充滿元氣的回到生活中,並且維持更長的舒適感。
Thumbnail
avatar
廢物芳療師Beth
2022-03-14