訊息丟失、重複、積壓
訊息丟失
1、訊息傳送出去因網路問題沒抵達伺服器
做好容錯方法,使用try catch 傳送訊息,沒傳送成功的訊息進行重試傳送。每一個訊息都做好日誌記錄,往資料庫中建立一個mq_message表儲存記錄,定期掃描資料庫,將失敗的訊息再發送一遍。
2、訊息抵達broker,broker要將訊息寫入磁碟(持久化)才算成功。此時Broker尚未持久化完成,宕機。
publisher生產者傳送訊息後,setConfirmCallBack()>confirm()>伺服器收到,加入確認回撥機制,確認成功的訊息,修改資料庫訊息狀態。
3、自動ACK狀態下。消費者收到訊息,但沒來得及消費然後宕機
一定開啟手動ACK,消費成功才移除,失敗或者沒來得及處理就noAck並重新入隊
1、做好訊息確認機制(publisher, consumer[手動ACK])
2、每一個傳送的訊息都在資料庫做好記錄。定期將失敗的訊息再次傳送
訊息重複
1、訊息消費成功,事務已經提交,ack時,機器宕機。導致沒有ack成功,broker的訊息重新由unaced變為ready,併發送給其它消費者
2、訊息消費失敗,由於重試機制,自動又將訊息傳送出去(允許)
3、成功消費,ack時宕機,訊息由unacked變為ready,broker又重新發送
消費者的業務消費介面應該設計為冪等性的。
使用防重表(redis/mysql),傳送訊息每一個都有業務的唯一標識,處理過就不用處理
rabbitMQ的每一個訊息都有redelivered欄位,可以獲取是否是被重新投遞過來的,而不是第一次投遞過來的
訊息積壓
1、消費者宕機積壓
2、消費者消費能力不足積壓
3、傳送者傳送流量太大
上線更多的消費者,進行正常消費
上線專門的佇列消費服務,將訊息先批量取出來,記錄資料庫,離線慢慢處理