假設我有兩種型別的訊息。訊息A 和訊息B。
- MessageA 在 DB 中創建一個條目。
- MessageB 更新 DB 中的條目。
大多數情況下,MessageA 與 MessageB 以長間隔發送。但是,在某些情況下,兩條訊息彼此相隔數秒發送。MessageA 可能仍在創建 DB 條目,但 MessageB 嘗試更新不存在的條目。
如何處理這種情況?我知道有兩種選擇:
- 重試/死信佇列 - 訊息被發送回佇列并再次重試,直到達到最大傳遞計數并移動到死信佇列
- Defer - 訊息被延遲到被明確讀取
哪個是最佳實踐?
- 1 似乎很好,但仍然可能達到最大重試次數,但尚未創建資料庫條目。
- 2 看起來不錯,但是需要做額外的編碼和基礎設施(Redis 和后臺任務)來定期檢查延遲訊息
uj5u.com熱心網友回復:
還有第三種處理這些競爭條件的選項(這并不總是可能的,取決于訊息的性質):
- 當訊息 B 在訊息 A 之前到達時,將訊息資料以部分形式或特定的保存區域存盤在接收服務中。
- 當Message A 到達時,檢查是否有相同key 的Message B 資料,如果有則將兩條訊息一起處理。
一個實際的例子:假設我們有一個包含 Year Group 和 Student 物體的學校資料庫。要創建新學生,系統會發送一條包含所有學生詳細資訊的訊息。要創建新的年級組,將發送一條訊息,其中包含年級組名稱和應屬于該年級組的 StudentId 串列。
如果在收到所有學生之前收到年級組訊息,您可以創建一個僅包含學生 ID 的占位符學生物體(可能還有一個標志來標識它是占位符)。
收到學生訊息后,只需添加或更新現有記錄,并填寫所有學生詳細資訊。
如果您必須選擇列出的兩個選項之一,則取決于:
- Retry/Deadletter 當然要簡單得多,但只有在兩條訊息到達之間的最大延遲相對較短時才會起作用。它要脆弱得多。
- 訊息延遲將更加可靠。它也不需要那么復雜——你不需要Redis 和后臺任務,你可以在收到訊息 A 時檢查延遲的訊息 B。
uj5u.com熱心網友回復:
對于這種需要訊息順序的場景,Service Bus 提供了一項功能來確保按照它們最初發送的順序處理訊息 -訊息會話。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/420882.html
標籤:
