脈絡:企業正用訊息傳遞整合應用程式。

遞送失敗的各種原因#

若接收端收到無法處理的訊息,它該把訊息移到 Invalid Message Channel。但如果訊息系統根本沒能把訊息送到接收端呢?

訊息系統無法遞送的原因不少:

  • 訊息系統可能沒有把該訊息的通道設定正確
  • 該通道可能在訊息送出後、遞送前(或訊息還在等待被接收時)被刪除
  • 訊息可能在被遞送前過期(見 Message Expiration);即使沒有明確設定過期時間,長時間無法遞送的訊息仍可能逾時
  • 一則帶有 Selective Consumer 條件、卻被所有人忽略的訊息,永遠不會被讀取,最終可能死掉
  • 訊息表頭可能有問題,導致它無法被成功遞送

幾種糟糕的處置#

訊息系統一旦判定無法遞送,就得對這則訊息做點什麼:

  • 原地擱著——會把系統堆滿
  • 退回寄件端——但寄件端不是接收者,偵測不到遞送
  • 直接刪除、祈禱沒人發現——這對「已經成功送出、並期待它被遞送、接收與處理」的寄件端來說,很可能造成問題

解法#

實作細節#

Dead Letter Channel 的具體運作方式取決於各訊息系統的實作(如果它有提供的話)。這個通道可能被稱為「dead message queue」或「dead letter queue」。

典型作法是:訊息系統安裝的每台機器都有自己本地的 Dead Letter Channel。這樣不論訊息死在哪台機器上,都能從一個本地佇列搬到另一個本地佇列,不必承受任何網路上的不確定性;同時也記錄下訊息是在哪台機器上死掉的。訊息系統搬動訊息時,可能還會記錄它原本應該被遞送到哪個通道。

死信與無效訊息的差別#

  • 死信——訊息系統無法成功遞送
  • 無效訊息——訊息被正確遞送了,但接收端無法處理

兩者的判定者也不同:

  • 是否該移到 Dead Letter Channel,是訊息系統對訊息表頭所做的評估
  • 是否該移到 Invalid Message Channel,是接收端因為訊息內文或它所關心的特定表頭欄位而做的決定

從接收端的角度看,死信的判定與處理像是自動發生的,而無效訊息則必須由它自己處理。

這也意味著:使用訊息系統的開發者只能接受該系統所提供的死信處理方式,但可以自行設計無效訊息的處理——包括處理那些「看起來已經死了、但訊息系統並不處理」的訊息。

範例:股票交易

在股票交易系統中,想執行交易的應用程式會送出一則交易請求。為了確保交易在合理時間內(也許五分鐘)被接收,請求方把該請求的 Message Expiration 設為五分鐘。

若訊息系統在這段時間內無法遞送該請求,或交易應用程式沒有及時從通道讀取它,訊息系統就會把該訊息從交易請求通道移到 Dead Letter Channel。

交易系統可能會想監控系統的死信通道,以判斷自己是否漏掉了某些交易。