為了防止訊息重複消費導致業務處理異常,Simple Message Queue (formerly MNS)的消費者在接收到訊息後,需要根據業務唯一標識對訊息做等冪處理。本文介紹消費等冪的概念、適用情境以及處理方法。
什麼是消費等冪
在訊息佇列情境中,消費等冪處理是指即使因為某些原因(如網路問題、系統故障等)導致同一條訊息被多次發送給消費者,通過等冪性設計也能保證最終的商務邏輯只被執行一次,避免因為重複消費而導致資料錯誤或業務結果不一致的情況。
例如,在支付情境下,Consumer消費扣款訊息,對一筆訂單執行扣款操作,扣款金額為100美元。如果因網路不穩定、系統故障等原因導致扣款訊息重複投遞,Consumer重複消費了該扣款訊息,但最終的業務結果是只扣款一次,計費100美元,且使用者的扣款記錄中對應的訂單只有一條扣款流水,不會多次扣除費用。那麼這次扣款操作是符合要求的,整個消費過程實現了等冪處理。
適用情境
等冪性在分布式系統中尤為重要,當系統出現網路抖動、系統故障、重複發送等異常時,訊息可能會被重複消費,等冪性可以在訊息重複時提高系統的可靠性和一致性。訊息重複的可能原因如下:
消費處理耗時超過訊息不可見時間:當某個消費者A處理訊息的時間長度超過了不可見時間,訊息會重新被投遞給消費者B,這種情況下會導致消費者A和B重複處理同一條訊息。
網路異常或抖動:訊息已被消費者處理成功,但網路異常導致
DeleteMessage
請求異常,訊息在不可見時間之後會被重新投遞給消費者。訊息佇列伺服器或消費者服務重啟:訊息已被消費者處理成功,但訊息佇列伺服器或者消費者服務重啟導致
DeleteMessage
請求處理失敗,訊息在不可見時間之後會被重新投遞給消費者。
處理方法
在訊息佇列中,通常以Message ID為等冪鍵對訊息進行等冪處理,但是由於不同的Message ID對應的訊息內容可能相同,有可能出現衝突(重複)的情況,所以真正安全的等冪處理不建議以Message ID作為處理依據。Simple Message Queue (formerly MNS)建議您以業務唯一標識作為等冪處理的關鍵依據。
唯一識別碼:為每個訊息分配一個唯一的標識符,消費者在處理訊息時,記錄已處理的業務唯一標識,當再次收到相同的訊息時,消費者可以直接跳過不再處理。
資料庫約束:在資料庫中設定唯一約束,當嘗試插入重複資料時會因為違反約束而失敗,從而實現等冪性。
業務狀態機器檢查:在處理訊息之前,消費者先檢查資料的目前狀態,比如資料是否已存在或已被處理。如果是,則直接返回,不再執行後續操作。
合併作業:對於某些操作,可以通過合并的方式來確保等冪性,即使執行多次,也只會產生一次最終結果。