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

更新於 發佈於 閱讀時間約 5 分鐘

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

Producer端送到RabbitMQ時丟失:

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

RabbitMQ儲存的訊息丟失:

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

RabbitMQ送到Consumer時丟失:

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

raw-image

處理方式:

為了確保訊息正確的送達RabbitMQ及Consumer正確的收到訊息,RabbitMQ為我們提供了兩種方式:

  1. 透過AMQP Transaction機制實現。
  2. 將Channel設定為confirm模式。

AMQP Transaction機制

主要有三個方法分別為:

  • txSelect(): 將當前的channel設定為transaction模式。
  • txCommit(): 提交事務。
  • txRollback(): 回滾事務。

可以看到下面流程中多了四個步驟,如此一來當資料量大的時候處理起來會比較沒有效率,因此一般應用狀況下很少採用Transaction機制。

raw-image
try {
channel.txSelect();
channel.basicPublish(...);
channel.txCommit();
} catch (e) {
channel.txRollback();
}

Confirm模式 — 生產端

首先我們一樣將通道設定為Confirm模式,Confirm模式與AMQP Transaction機制只能選一個使用。

channel.confirmSelect();

Confirm模式又分為以下三種方式:

1. 普通Confirm模式: 每發送一條消息就等待服務端回應一次。

這種方式較沒效率,每次丟一個訊息就得等待通知。
raw-image
try {
// 發送一條訊息
channel.basicPublish(...);
// 等待確認訊號
if(channel.waitForConfirms()){
// 發送成功
} else {
// 重送或其他處置
}
} catch(...) {
...
}

2. 批次Confirm模式: 發送一批消息後再等待服務端回應。

這種方式可以發送一批後再等待通知,乍看之下蠻有效率的,但如果訊息常常丟失,那麼我們也得批次重傳。
raw-image
try {
// 發送多條訊息
for (i = 0; i < batchSize; i++) {
channel.basicPublish(...);
}
// 等待確認訊號
if(channel.waitForConfirms()){
// 發送成功
} else {
// 重送或其他處置
}
} catch(...) {
...
}

3. 異步Confirm模式: 以Listener方式等待服務端回應。

raw-image

這邊以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收到後就認為已經消費完成會將該訊息刪除。

raw-image
留言
avatar-img
留言分享你的想法!
avatar-img
阿Han的沙龍
139會員
302內容數
哈囉,我是阿Han,是一位 👩‍💻 軟體研發工程師,喜歡閱讀、學習、撰寫文章及教學,擅長以圖代文,化繁為簡,除了幫助自己釐清思路之外,也希望藉由圖解的方式幫助大家共同學習,甚至手把手帶您設計出高品質的軟體產品。
阿Han的沙龍的其他內容
2024/09/04
相信對於這一篇感興趣的朋友們都已經玩過kafka的Schema Registry了吧! 沒玩過得朋友也沒關係, 歡迎至「【🔒Message Queue - Kafka】傳輸訊息的標準格式制定者 Schema Registry」了解一下這是什麼玩意兒, 好了, 廢話不多說, 讓我們直接切入主題吧
Thumbnail
2024/09/04
相信對於這一篇感興趣的朋友們都已經玩過kafka的Schema Registry了吧! 沒玩過得朋友也沒關係, 歡迎至「【🔒Message Queue - Kafka】傳輸訊息的標準格式制定者 Schema Registry」了解一下這是什麼玩意兒, 好了, 廢話不多說, 讓我們直接切入主題吧
Thumbnail
2023/06/25
為什麼要用Docker安裝? Docker是一個容器化平台, 就類似於我們早期虛擬機的VMWare、Virtual Box…等, 虛擬機平台一般, 只是面向的是伺服端, 供企業快速、簡單、輕量的佈署開發完成的程式軟體, 並將相關的環境依賴皆封裝成一包所謂的映像檔(image), 透過這樣的方式減少因
Thumbnail
2023/06/25
為什麼要用Docker安裝? Docker是一個容器化平台, 就類似於我們早期虛擬機的VMWare、Virtual Box…等, 虛擬機平台一般, 只是面向的是伺服端, 供企業快速、簡單、輕量的佈署開發完成的程式軟體, 並將相關的環境依賴皆封裝成一包所謂的映像檔(image), 透過這樣的方式減少因
Thumbnail
2023/06/16
對於軟體世界中Message Queue有興趣的朋友可以先閱讀這一篇「【資訊軟體知識】井然有序的處理機制 - Message Queue」建立基礎知識之後,再來看看這一篇會更容易進入情境唷! 這次就進入我們一般常見的MQ軟體「RabbitMQ」, 我們先以圖示來了解RabbitMQ的模型架構, 之後
Thumbnail
2023/06/16
對於軟體世界中Message Queue有興趣的朋友可以先閱讀這一篇「【資訊軟體知識】井然有序的處理機制 - Message Queue」建立基礎知識之後,再來看看這一篇會更容易進入情境唷! 這次就進入我們一般常見的MQ軟體「RabbitMQ」, 我們先以圖示來了解RabbitMQ的模型架構, 之後
Thumbnail
看更多
你可能也想看
Thumbnail
常常被朋友問「哪裡買的?」嗎?透過蝦皮分潤計畫,把日常購物的分享多加一個步驟,就能轉換成現金回饋。門檻低、申請簡單,特別適合學生與上班族,讓零碎時間也能創造小確幸。
Thumbnail
常常被朋友問「哪裡買的?」嗎?透過蝦皮分潤計畫,把日常購物的分享多加一個步驟,就能轉換成現金回饋。門檻低、申請簡單,特別適合學生與上班族,讓零碎時間也能創造小確幸。
Thumbnail
這種方式主要是Consumer處理訊息失敗時, 再把訊息送回去重新排隊, 在RabbitMQ的架構下非常簡單, 只要在Error Handling的地方發送nack訊號回去即可。 這種方式雖然簡單, 但是也存在著一些風險: 由於Queue為了確保順序性, 因此該訊息會被重新排到最前面, 如此一來該訊
Thumbnail
這種方式主要是Consumer處理訊息失敗時, 再把訊息送回去重新排隊, 在RabbitMQ的架構下非常簡單, 只要在Error Handling的地方發送nack訊號回去即可。 這種方式雖然簡單, 但是也存在著一些風險: 由於Queue為了確保順序性, 因此該訊息會被重新排到最前面, 如此一來該訊
Thumbnail
很多人都說,做生意就是要清清楚楚,規矩講清楚,不能有不明不白的地帶。 我非常贊同這樣的說法,做事也盡量朝這方面去執行。但有實際業務經驗的人就會知道,“有些時候”雙方對同一件事情的解釋,保有不清晰的模糊地帶,反而才能順利解決事情。 這邊特別標“有些時候”,就表示大部分時候,清清楚楚講明白,是更好的方式
Thumbnail
很多人都說,做生意就是要清清楚楚,規矩講清楚,不能有不明不白的地帶。 我非常贊同這樣的說法,做事也盡量朝這方面去執行。但有實際業務經驗的人就會知道,“有些時候”雙方對同一件事情的解釋,保有不清晰的模糊地帶,反而才能順利解決事情。 這邊特別標“有些時候”,就表示大部分時候,清清楚楚講明白,是更好的方式
Thumbnail
A產品的標準交期為4-6個星期。 報價單內容 產品:A產品 售價:20,000塊美金 交期:約6個星期。 正確的回覆 某年某月的17日。 業務:您好,請確認報價單內容,如果內容正確,請簽名回傳。 客戶:您好,訂單確認,我們會發送正式訂單給您,我們有點急,您先安排生產,訂單款項我們會在月底前付清。
Thumbnail
A產品的標準交期為4-6個星期。 報價單內容 產品:A產品 售價:20,000塊美金 交期:約6個星期。 正確的回覆 某年某月的17日。 業務:您好,請確認報價單內容,如果內容正確,請簽名回傳。 客戶:您好,訂單確認,我們會發送正式訂單給您,我們有點急,您先安排生產,訂單款項我們會在月底前付清。
Thumbnail
隨時收發信件、讓客戶或同事可以隨時得到答案,免去似乎永無止境的會議和電話,聽起來可以讓整個組織更具生產力,理論上應該幫助我們省下很多時間(畢竟節省了很多會議,也不用等到別人有空接電話),但它最終讓辦公室裡的每個人都處於焦慮、每天花了太多時間在枝微末節的來回溝通上,也沒有如我們預期地省下時間...
Thumbnail
隨時收發信件、讓客戶或同事可以隨時得到答案,免去似乎永無止境的會議和電話,聽起來可以讓整個組織更具生產力,理論上應該幫助我們省下很多時間(畢竟節省了很多會議,也不用等到別人有空接電話),但它最終讓辦公室裡的每個人都處於焦慮、每天花了太多時間在枝微末節的來回溝通上,也沒有如我們預期地省下時間...
Thumbnail
一早就被客戶扯斷理智,看到LINE的當下真的蠻氣的,客戶百百款,遇到情況也是百百款,都需要會好好的溝通才能有後續。我當下是好好溝通的,也讓這個專案順利結案,也順勢廣告自己公司的優勢與服務。​ ▋ 回想,理智斷掉過程是這樣....​ 劈哩批啦的客互打了一堆,我沒有說話的機會啊~~​ 讀書會資訊
Thumbnail
一早就被客戶扯斷理智,看到LINE的當下真的蠻氣的,客戶百百款,遇到情況也是百百款,都需要會好好的溝通才能有後續。我當下是好好溝通的,也讓這個專案順利結案,也順勢廣告自己公司的優勢與服務。​ ▋ 回想,理智斷掉過程是這樣....​ 劈哩批啦的客互打了一堆,我沒有說話的機會啊~~​ 讀書會資訊
Thumbnail
在上一篇文章中,我分享了開始接案後整理出的合約注意事項,我們接著來看看我對於接案中「溝通」的一些心得吧!
Thumbnail
在上一篇文章中,我分享了開始接案後整理出的合約注意事項,我們接著來看看我對於接案中「溝通」的一些心得吧!
Thumbnail
當我們暫時失去人與人的連結,每天面對海量湧進的真假資訊,真是令人焦躁!在那麼多資訊中,每個人都可以選擇相信哪種說法,但如果我是對的,不代表對方是錯的,最近跟客戶的往返溝通中,因為在對立的框架中思考,反而讓雙方陷入更深的泥淖。
Thumbnail
當我們暫時失去人與人的連結,每天面對海量湧進的真假資訊,真是令人焦躁!在那麼多資訊中,每個人都可以選擇相信哪種說法,但如果我是對的,不代表對方是錯的,最近跟客戶的往返溝通中,因為在對立的框架中思考,反而讓雙方陷入更深的泥淖。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News