先分類失敗原因,不要看到死信就直接重送
訊息進入死信佇列,只代表它超過重試上限或被消費端拒絕,並不代表再次投遞就會成功。常見原因包括暫時性依賴故障、訊息格式或版本不相容、業務資料不合法、權限與設定錯誤,以及程式本身的確定性缺陷。若沒有先分類,批次重送可能只是把同一個錯誤重新製造一次,甚至讓下游 API、資料庫或第三方服務再次過載。
我們通常以三個維度標記死信:失敗原因決定應修正系統、資料還是設定;可重送性判斷訊息能否原樣處理、需要轉換,或應永久隔離;業務風險則評估重複扣款、重複通知、狀態倒退與資料外洩等影響。分類最好由錯誤碼、例外類型、訊息版本、來源服務及首次失敗時間共同產生,不要只靠一段難以查詢的錯誤文字。
- 暫時性錯誤:逾時、限流或短暫連線失敗,通常可在依賴服務恢復後重送。
- 確定性程式錯誤:同一輸入必然觸發缺陷,應先部署修正,再用小批次驗證。
- 結構或版本錯誤:需要升級消費者、套用轉換器,或保留舊版處理路徑。
- 業務規則錯誤:缺少必要欄位、參照資料不存在或狀態不允許,需由資料或流程負責人判定。
- 安全與權限錯誤:憑證、租戶範圍或存取政策異常,未釐清前不應重送。
把重送設計成受控部署,而不是佇列搬運
可靠的重送流程應有明確閘門。開始前先保存死信範圍、查詢條件、訊息數量與代表性樣本,並確認造成失敗的依賴或程式已恢復。接著檢查消費端是否具備冪等性:同一事件再次出現時,是否會以事件 ID、業務鍵或寫入版本拒絕重複副作用。若不能保證冪等,就需要補償邏輯、去重紀錄,或由人工核准高風險訊息。
重送不應直接把全部訊息倒回主要佇列。先建立不可變的重送批次清單,從少量樣本開始,限制速率與並行度,並保留立即暫停的開關。監控至少要涵蓋成功率、再次進入死信的原因、消費延遲、下游錯誤、資料庫負載與外部服務限流。若訊息具有順序要求,應依分割鍵或業務實體逐組重送;任意平行化可能讓較新的狀態先被舊事件覆寫。
另一個容易忽略的問題是部分成功。消費者可能已寫入資料庫,卻在回覆確認前失敗;也可能完成 ERP 更新,但沒有送出後續通知。重送前必須知道每個步驟的提交邊界,並以現有事實決定繼續、跳過或補償,而不是把整段流程從頭執行。
建立可觀察、可中止的排空程序
排空死信佇列的目標不是讓數字歸零,而是讓每則訊息得到可解釋的處置。可重送訊息應帶著原始訊息 ID、重送批次 ID、分類結果與操作原因進入重送通道;不可重送者則留在隔離儲存區,等待修復、人工處理或到期清理。不要修改唯一的原始副本,否則後續很難還原事件內容或證明操作過程。
執行時採分階段放量:先驗證少量樣本的業務結果,再逐步增加批次大小。停止條件應在作業前寫清楚,例如同類錯誤再次出現、下游延遲持續上升、重複副作用被偵測,或資料核對不一致。這些條件要能自動暫停,而不是等值班工程師從圖表中猜測是否該停。
- 凍結並記錄本次處理範圍,避免新死信混入既有批次。
- 對訊息做結構驗證、租戶範圍檢查與敏感資料遮罩。
- 以小批次重送,逐批核對業務狀態及下游副作用。
- 為每則訊息留下成功、再次失敗、跳過或隔離的最終結果。
- 達到停止條件時保留游標,使作業能從已知位置安全續跑。
只有在證據完整後,才刪除或封存死信
清理政策應區分成功重送、永久無效與仍待調查三種狀態。成功重送不等於立即刪除;應先確認下游資料、通知及整合狀態一致,並保留足以支援追蹤的稽核紀錄。永久無效的訊息也需要處置原因與核准依據。仍待調查的項目則不應因儲存期限將到而悄悄消失。
保存期限要同時考慮法規、個資、事故調查需求與儲存成本。封存資料應限制存取權限並加密,且避免把完整敏感內容複製到日誌或工單。到期刪除應依明確政策執行,記錄刪除範圍、時間與操作者,但不在稽核紀錄中再次保存原始敏感資料。
成熟的死信流程最後會形成閉環:分類結果回饋到告警規則,常見錯誤轉成驗證或相容性測試,重送紀錄用來改善冪等與可觀察性。若系統橫跨 LINE、ERP、CRM、雲端服務與 IoT 平台,整合團隊的價值通常在於釐清跨系統提交邊界與責任歸屬,讓死信處理成為可演練的維運程序,而非事故當下的臨時腳本。