RabbitMQ消息丟失、積壓、重復等解決方案


消息丟失

1、只要訂單完成我們就會發送一條消息給MQ,這個途中突然MQ服務器網絡中斷,導致消息無法抵達

做好容錯方法需要在消息發送前加上異常處理

 try {
  rabbitTemplate.convertAndSend("order-event-exchange", "order.release.other", orderTo);
    } 
catch (Exception e) {
   //將沒法送成功的消息進行重試發送
    }

還可以將消息存入數據庫,把失敗的消息定期重新再發一遍

2、當消息發送給MQ,通過Brock通過交換機抵達隊列,MQ關機了,只有抵達隊列才能實現消息持久化

這時候需要使用生產者的確認機制

image-20211021204726680

只要消息收到了會自動持久化,如果進入另一個回調方法說明報錯了,需要修改數據庫使消息重發

3、自動ACK的狀態下。消費者收到消息,但沒來得及消息然后宕機

一定開啟手動ACK,消費成功才移除,失敗或者沒來得及處理就noAck並重新入隊

消息重復

1、消息消費成功,事務已經提交,ack時,機器宕機。導致沒有ack成功,Broker的消息重新由unack變為ready,並發送給其他消費者

image-20211021205648407

在ack的時候宕機,導致消息沒有確認,又需要重新發送

2、消息消費失敗,由於重試機制,自動又將消息發送出去

image-20211021205941757

關閉訂單的時候,沒有成功,又重新進入隊列再次執行,這種是可以允許的

解決辦法:

  • 消費者的業務消費接口應該設計為冪等性的。比如扣庫存有工作單的狀態標志
  • 使用防重表(redis/mysql),發送消息每一個都有業務的唯一標識,處理過就不用處理
  • rabbitMQ的每一個消息都有redelivered字段,可以獲取是否是被重新投遞過來的,而不是第一次投遞過來的

image-20211021210504681

判斷當前消息是否是第二次及以后被派發過來的

消息積壓

  • 消費者宕機積壓

  • 消費者消費能力不足積壓

  • 發送者發送流量太大

    • 上線更多的消費者,進行正常消費

    • 上線專門的隊列消費服務,將消息先批量取出來,記錄數據庫,離線慢慢處理

這也是實現了柔性事務-可靠消息+最終一致性解決方案

做好消息確認機制(生產者、消費者)+手動確認機制

並把消息在數據庫做好記錄


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM