RabbitMQ 訊息的可靠投遞

2022-07-04 09:54:11 字數 2322 閱讀 7176

可靠性投遞:

1、保障訊息能夠成功發出

2、保障rabbitmq(broker)能夠成功接收。接收指的是:broker接收到生產者傳送的訊息,放到exchange中,分發給對應的queue,交付給對應的消費者。

3、傳送端要收到broker的確認應答,確認broker已收到|處理訊息

4、完善的訊息補償機制。傳送端沒收到broker的確認應答,不知道訊息是否成功投遞成功,這時候就需要做一些補償處理,比如重新投遞。

rabbitmq的server又叫做broker,接收客戶端的連線,實現amqp實體服務,包含exchange、queue等多種元件。

說白了,broker就是rabbitmq伺服器。

實現訊息可靠性投遞的、常見的2種解決方案

第一種方案   訊息狀態打標

1、生產者將訊息入庫、訊息狀態入庫。

比如使用者下單,產生乙個order物件,把這個order物件資料持久化到資料庫中

單獨用一張表來儲存訊息狀態:

用外來鍵關聯訊息(比如關聯訂單表的id),

設定乙個status列記錄訊息投遞狀態,預設值為0,表示訊息未投遞到broker;

設定乙個時間列,記錄訊息投遞時間;

設定乙個重試次數列,記錄重新投遞的次數,預設值為0。

2、生產者傳送訊息到broker

把order物件傳送到broker,因為訊息都要轉換為byte[ ]傳送,什麼型別都可以。

3、生產者接收到broker的確認應答,將資料庫中該條訊息的狀態修改為1,表示成功投遞

4、分布式系統的定時任務

如果訊息投遞一段時間後,未收到broker的確認應答,怎麼補償處理?

使用定時任務來做:

生產者每隔一段時間,比如5min,啟動一條執行緒來查詢資料庫中重試次數達到指定值(比如3)、且投遞時間已超過指定值(比如5min)的訊息,將其狀態修改為2,表示重試指定次數後仍未能成功投遞;

再查詢狀態為0、且傳送時間已超過指定時間的訊息,重新投遞,並更新投遞時間為當前時間、重試次數+1;

第一種方案存在的問題

生產者執行定時任務也有額外的開銷,生產者要進行2方面的資料庫io操作(訊息本身+訊息狀態),io是很花時間的,在高併發的情況下,資料庫效能很容易成為系統效能的瓶頸。

併發量大的情況下,第一種方案嚴重拉低生產者的效能。

相比之下,第二種方案用得更多,但稍微複雜一點。

第二種方案  延時再次投遞訊息

1、生產者將訊息入庫,並將訊息傳送給broker,broker將訊息放到對應的queue1中

2、消費者監聽queue1,處理訊息,處理一條訊息後產生一條新訊息作為確認(繫結queue2),比如以order的id作為新訊息,總之要能唯一標識處理的訊息。

3、消費者將產生的訊息傳送給broker,broker將訊息放到queue2中(注意不是消費者監聽的queue1)

4、單獨寫乙個callback service(**服務),來監聽queue2,把queue2中的訊息入庫,比如放在tb_msg_processed表中,一條記錄代表一條已被消費者處理的訊息

5、生產者傳送訊息後,延時再次傳送這條訊息(繫結queue3),比如3min|5min後再次傳送這條訊息。

6、**服務監聽queue3,把queue中訊息與資料庫中的記錄對比,比如把queue3獲取到的order的id取出來,查詢tb_msg_processed中有沒有這個order id,有就說明投遞成功;沒有就說說明未投妥,**服務rpc通知生產者(傳遞order id),生產者從資料庫查詢該條訊息的資料(order物件),重新投遞(queue1)——重新走一遍流程。

第一種方案消費者使用資料報來確認應答(ack),第二種由消費者自己產生一條訊息來確認應答。

整個流程中,生產者又叫做upstream service(上游服務),消費者又叫做downstream service(下游服務)。

第二種方案的優缺點

相較於第一種方案,第二種方案多寫乙個服務,每對生產者——消費者都使用乙個額外的queue來確認,**服務開發成本高些、略微複雜些;

部署**服務又要使用、維護額外的機器,成本變高了。

但生產者的資料庫io操作減少了,提公升了效能。只要效能上去,稍微增加點成本完全可以接受。

說明(1)訊息入庫完成,然後傳送訊息(order物件)到broker,注意順序

(2)分布式事務對效能的影響很大,併發量中小的可以加事務,如果併發量很大,事務會嚴重拉低效能,不建議加事務(能不加就不加)

(3)不管是第一種、還是第二種,都很難做到100%的投遞成功。優先考慮能夠扛得住高併發(效能),在保證效能的前提下盡可能提高訊息投遞的可靠性

RabbitMQ如何保證訊息的可靠性投遞

目前來說,現在有兩種方案實施 1.資料庫持久化方案 2.訊息延遲投遞方案 資料庫持久化方案 流程 1.將業務訂單資料和生成的message進行持久化操作 一般情況下插入資料庫,這裡如果分庫的話可能涉及到分布式事務 2.將message傳送到broker伺服器中 3.通過rabbitmq的confir...

《RabbitMQ》如何保證訊息的可靠性

1.1 事務機制 amqp協議提供了事務機制,在投遞訊息時開啟事務支援,如果訊息投遞失敗,則回滾事務。自定義事務管理器 configuration public class rabbittranscation bean public rabbittemplate rabbittemplate con...

RabbitMQ系列 如何保證訊息的可靠傳輸

訊息的可靠投遞除了需要硬體,網路,訊息中介軟體等的可靠保證外,還需要生產者,消費者來共同保證來完成。一條訊息從生產者產生,到傳送到交換機,並被投遞到佇列,並最終被消費者消費,這整個路徑上,途徑的每乙個地方都要保證訊息的可靠性。其實,官方文件reliability guide已經總結了訊息系統安全的方...