消息丟失
1、只要訂單完成我們就會發送一條消息給MQ,這個途中突然MQ服務器網絡中斷,導致消息無法抵達
做好容錯方法需要在消息發送前加上異常處理
try {
rabbitTemplate.convertAndSend("order-event-exchange", "order.release.other", orderTo);
}
catch (Exception e) {
//將沒法送成功的消息進行重試發送
}
還可以將消息存入數據庫,把失敗的消息定期重新再發一遍
2、當消息發送給MQ,通過Brock通過交換機抵達隊列,MQ關機了,只有抵達隊列才能實現消息持久化
這時候需要使用生產者的確認機制

只要消息收到了會自動持久化,如果進入另一個回調方法說明報錯了,需要修改數據庫使消息重發
3、自動ACK的狀態下。消費者收到消息,但沒來得及消息然后宕機
一定開啟手動ACK,消費成功才移除,失敗或者沒來得及處理就noAck並重新入隊
消息重復
1、消息消費成功,事務已經提交,ack時,機器宕機。導致沒有ack成功,Broker的消息重新由unack變為ready,並發送給其他消費者

在ack的時候宕機,導致消息沒有確認,又需要重新發送
2、消息消費失敗,由於重試機制,自動又將消息發送出去

關閉訂單的時候,沒有成功,又重新進入隊列再次執行,這種是可以允許的
解決辦法:
- 消費者的業務消費接口應該設計為冪等性的。比如扣庫存有工作單的狀態標志
- 使用防重表(redis/mysql),發送消息每一個都有業務的唯一標識,處理過就不用處理
- rabbitMQ的每一個消息都有redelivered字段,可以獲取是否是被重新投遞過來的,而不是第一次投遞過來的

判斷當前消息是否是第二次及以后被派發過來的
消息積壓
-
消費者宕機積壓
-
消費者消費能力不足積壓
-
發送者發送流量太大
-
上線更多的消費者,進行正常消費
-
上線專門的隊列消費服務,將消息先批量取出來,記錄數據庫,離線慢慢處理
-
這也是實現了柔性事務-可靠消息+最終一致性解決方案
做好消息確認機制(生產者、消費者)+手動確認機制
並把消息在數據庫做好記錄
