冪等性:構建穩健分佈式系統的關鍵

爲什麼冪等性是關鍵?

在現代分佈式系統中,可用性是關鍵因素,這意味着你需要構建重試機制和處理失敗及恢復的方法。這也意味着你可能會在系統中重複處理相同的操作,但如果你的應用程序不瞭解這一點,並將其視爲一個全新的請求,它將產生不可預期的結果。如果是處理支付或管理電子商務訂單的應用程序,這會導致巨大的財務損失和不可挽回的損害。

那麼,我們該怎麼做才能保證多次執行操作的結果與僅執行一次的結果相同呢?

讓系統具備冪等性!!!

什麼是冪等性?

冪等性是指一個系統或過程在多次執行相同操作時能夠產生相同結果的能力。冪等性保證了多次執行相同操作不會引入意外的副作用,從而防止了意外的重複處理或不期望的更改。例如,在重複檢查中,冪等系統確保重複請求不會導致重複處理,因此如果向系統發出重複請求,冪等系統要麼忽略它,要麼返回首次處理的狀態。

等一下,我有點困惑!!!重複檢查和冪等操作是一樣的嗎?

重複檢查 vs 冪等性

重複檢查旨在防止不必要的狀態更改,確保我們不會多次處理同一事件,而冪等性則允許我們再次處理相同的事件,但結果將是相同的。簡單來說,通過冪等性,我們可以在至少一次的消息傳遞系統中處理重複事件,確保多次處理相同事件仍然產生相同的效果。換句話說,冪等性是處理重複事件的最佳方式。

這聽起來不錯。但我們該如何實現它,可能會遇到什麼挑戰呢?

冪等性實現策略

爲了構建冪等性,最重要的任務是爲每個請求找到或創建一個冪等鍵。我制定了一個簡單的算法策略,並添加了一些標準鍵來構建穩健的冪等性。

策略

  1. 爲每個請求找到一個唯一的關聯標識符,我們可以依賴它並存儲在數據存儲中,以便檢查每個傳入請求。2. 如果沒有唯一標識符,可以通過對有效負載進行哈希處理來創建校驗和,並將其用於冪等性。3. 如果有效負載包含 UUID 或時間戳(如創建時間戳),可能在每次重試時會改變,儘可能忽略這些字段並創建校驗和。如果無法忽略,請確保使用硬編碼值。4. 對於 POST API,在請求頭中添加 x-idempotency-key,並要求消費者提供一個唯一標識符和一個可選的過期時間。5. 在服務網格中,服務協作執行任務時,使用狀態變化模型和重複檢查來確保系統的冪等性。6. 定義冪等鍵的有效期,例如你的數據存儲將存儲該鍵的時間長度。7. 可以使用如下示例中展示的通用模型來創建複合冪等鍵。
public class IdempotentKey {
private String key;    // 鍵
private long ttl;      // 生存時間
private String result; // 響應
}

冪等鍵

可用於構建冪等鍵的標準鍵:

UUID v4: 使用標準的 java.util.UUID 創建唯一標識符。• 有效負載哈希: 創建請求有效負載的哈希(摘要)作爲冪等鍵,保證相同有效負載的請求生成相同的鍵。• 鍵元素: 在冪等鍵中包含用戶 ID、交易詳情和時間戳等唯一參數,創建精確識別的複合鍵。• 令牌: 發放並要求客戶端在請求中包含令牌,作爲冪等鍵和安全措施。• 時間戳: 使用時間戳或組合時間戳作爲時間基冪等鍵,確保操作在定義的時間窗口內是冪等的。

冪等模型

冪等性如何實現,以及如何處理不同場景?下面是我開發的冪等性的 shell 級實現。

  1. 客戶端將有效負載 “p12345” 發送到接收服務進行處理。客戶端可以選擇在請求頭中發送 x-idempotency-key,作爲處理的冪等鍵。如果客戶端未發送冪等鍵頭,則我們可以通過對有效負載進行哈希處理創建一個,並將鍵存儲在 Mapper 中。(如果訂單 ID 尚未生成,系統將爲每個新請求生成一個)。2. 接收服務將執行重複檢查,查看訂單是否已存在系統中;如果是,它將返回訂單的當前狀態;如果不是,它將持久化訂單及其當前狀態—RCVD。3. 接下來,接收服務可以進行必要的驗證並進行支付。如果成功,則加載訂單的當前狀態(因爲它可能已經是 PAID 狀態),如果狀態是 RCVD,則處理支付並更新狀態爲—PAID。如果接收服務由於網絡故障或其他原因重試支付現有訂單,我們的狀態模型將救場,重試將被拒絕,因爲訂單已經是 PAID 狀態。4. 成功支付後,接收服務將訂單發送進行履行。如果訂單狀態是 PAID,訂單將被履行並達到最終狀態—FULFILLED。如果此處發生重試,狀態模型將救場。5. 注意,如果接收服務或支付服務有多個實例(pods)運行,確保在更新狀態時擁有集羣鎖。6. 另一個要點是,爲了加快冪等性的處理,可以使用緩存層存儲映射信息,但在我的案例中,主數據存儲足以處理高負載(避免過早優化)。

這是冪等性的一個演示用例。對於生產環境,你需要考慮你的用例,以及如何將該模型應用於實際場景。

結論

冪等性對於構建大規模、數據完整性不受影響的彈性分佈式系統至關重要。冪等性的重試策略是分佈式事務的一個優秀替代方案,後者更復雜且隨着擴展更難以管理。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/NwqnwdfbojrKqGfUFBizPg