rabbitmq如何保證消息的可靠性
1、保證消息不丟失
1.1、開啟事務(不推薦)
1.2、開啟confirm(推薦)
1.3、開啟RabbitMQ的持久化(交換機、隊列、消息)
1.4、關閉RabbitMQ的自動ack(改成手動)
2、保證消息不重復消費
2.1、冪等性(每個消息用一個唯一標識來區分,消費前先判斷此標識有沒有被消費過,若已消費過,則直接ACK)
rabbitmq如何保證消息的順序性
將消息放入同一個交換機,交給同一個隊列,這個隊列只有一個消費者,這個消費者只允許同時開啟一個線程
rabbitMQ保證消息不丟失的具體方案
前提:
(1)開啟confirm
(2)開啟RabbitMQ的持久化(交換機、隊列、消息)
(3)關閉RabbitMQ的自動ack(改成手動)
(4)配置消費重試次數,消費重試間隔時間等
1、保證投放消息不丟失
(1)先將消息放入生產者Redis(此時消息的狀態為未投放),再放入隊列
(2)根據conform(ReturnCallback和ConfirmCallback)的結果來確定消息是否投遞成功,
投遞成功的,修改生產者redis中此消息的投遞狀態為已投遞
投遞失敗的將會放入失敗的Redis,並從生產者Redis中刪除,由定時任務定期掃描並重新投遞
(3)需要一個專門的定時任務掃描生產者Redis中存放了一定時間,但是狀態還是未投放的消息
此消息會被認為已經投遞,但是沒有任何反饋結果(由於不可知因素,導致沒有ReturnCallback,也沒有ConfirmCallback),
此類消息被掃描到后,會放入失敗的Redis,並從生產者Redis中刪除,由定時任務定期掃描並重新投遞
(4)還需要一個專門的定時任務掃描生產者Redis中存放了很久,仍然未消費的數據(狀態為已投遞),此類消息被掃描到后,會放入失敗的Redis,並從生產者Redis中刪除,由定時任務定期掃描並重新投遞
(5)掃描失敗的Redis的定時任務都遵循一條原則,一條消息最多被重新投遞三次,若投遞了三次仍然失敗,則記錄日志,記錄到數據庫,不會再投遞,需要人工干預處理
2、保證消費消息不丟失
(1)消費者取到消息后,從消息中取出唯一標識,先判斷此消息有沒有被消費過,若已消費過,則直接ACK(避免重復消費)
(2)正常處理成功后,將生產者Redis中的此消息刪除,並ACK(告訴server端此消息已成功消費)
(3)遇到異常時,捕獲異常,驗證自己在消息中設定的重試次數是否超過閥值,若超過,則放入死信隊列,若未超過,則向將消息中的重試次數加1,拋出自定義異常,進入重試機制
(4)有專門的消費者用於處理死信隊列中消費多次仍未消費成功的數據,可以記錄日志,入庫,人工干預處理
集群部署方案
rabbitmq有兩種集群部署方案
1、普通模式
rabbit01和rabbit02兩個節點僅有相同的元數據,即隊列的結構
消息實體只存在於其中一個節點rabbit01(或者rabbit02)
當消息進入rabbit01節點的Queue后,consumer從rabbit02節點消費時,RabbitMQ會臨時在rabbit01、rabbit02間進行消息傳輸,把A中的消息實體取出並經過B發送給consumer
2、鏡像模式
把需要的隊列做成鏡像隊列,存在與多個節點,消息實體會主動在鏡像節點間同步,屬於RabbitMQ的HA方案。
副作用也很明顯,除了降低系統性能外,如果鏡像隊列數量過多,加之大量的消息進入,集群內部的網絡帶寬將會被這種同步通訊大大消耗掉。