面試官:對于 MQ 中的消息重復消費說說的你的理解
今天這是MQ消息消費必問面試的第三個問題,重復消費。如果你還沒有看消息丟失、消息堆積,可以先去點擊鏈接進行查看。
首先我們先看一下消息重復消費的定義,就是字面意思,一條消息被消費執行了多次。可以是一個消費者消費了多次,也可以是多個消費者消費了同一條消息。

一、重復消費消息對系統的影響
消息重復消費可能導致數據在數據庫中被重復插入,這其實還好,重復插入只要不是影響業務,在查詢時去重也可以解決,俗稱治標不治本。
如果是通知類消息,用戶可能會收到多條通知,對于用戶的體驗會有所影響。
但是消息的重復消費最壞的就是導致數據的不一致,如果是訂單類的系統,多次消費帶來的不一致可能是致命的錯誤,例如多次扣款、超賣等。
消息重復消費在系統高并發的時候會嚴重的影響系統性能,消費者吞吐量下降造成消息堆積等。
二、消息發生重復消費的原因
消息重復消費產生的原因有很多,比如上一篇文章消息堆積中產生消息堆積的原因之一,消費者異常多次重試消費。
- 消費者在消費消息的過程中,業務代碼異常一直重試,沒有對異常行為進行控制造成單條消息卡住,一直重復消費。
- 消費者應答機制不合理,在消費者處理完業務之后無法正常應答或者因網絡原因應答失敗。
- 配置錯誤,手動ack,消費者消費完成之后沒有成功ack。
三、消息重復消費解決方案
- 合理配置應答機制,手動應答,消費者業務處理盡量簡單,對各種異常做好處理,增強應用系統健壯性。
- 消息重試次數增加限制,防止消息一直重試。
- MQ中配置合理的消息語義,保證至少一次,然后業務端做好去重。
- 增加消息唯一標識,消費過的消息不在進行處理。
- 消費端業務邏輯處理冪等,保證不管消費多少次都與消費一次的結果相同。
- 使用死信隊列,當消息一直重復消費時加入死信隊列。
- 監控,發現異常消息消費及時告警。
總結
消息重復產生的原因可以概括為兩點,應答失敗與業務異常循環消費單條消息。
對于消息的重復消費,業界用的最多的,還是消息唯一標識加冪等。消費端代碼盡可能的對異常情況做好處理,保證在發生異常之后可以正確的應答。
對于消息唯一標識這里簡單說兩句,可以生產者加入消息唯一標識,消費者也加入唯一標識,生產者與消費者不必相同,保證消息唯一即可。
在消費者進行消費消息時,首先根據消息唯一標識判斷是否已經消費過,可以使用 Redis 或者 MySQL 中的唯一索引等方式,然后來判斷該消息是否可以被消費。






















