冪等性(Idempotence) 是分散式系統和微服務架構中的一個關鍵概念, 尤其是在處理 retry 與 防止重複操作時非常重要. 簡單來說, 冪等性意味著無論你發送相同的命令多少次, 結果都是一樣的, 系統不會改變其狀態, 甚至可能不會執行重複的操作. 對於網路異常或請求超時等情況下非常重要, 因為 client 可能會 retry, client 屬於我們不可控的對象, 但我們服務方會希望避免同一操作被重複執行.
冪等操作
該操作是冪等的, 表示重複執行不會產生額外的影響或狀態的改變. 例如, 使用相同的數據來更新資料的狀態, 或調用建立紀錄的端點, 這些都不會導致重複紀錄的產生.
冪等欄位(Idempotency Key)
在許多系統的設計中, 請求或命令中都會包含一個唯一識別符(冪等欄位), 以確保如果請求被retry, 系統能夠識別這是重複操作, 可以選擇跳過執行. 冪等欄位通常是由client端產生.
Retry Attack(重試攻擊) 是一種與網絡安全相關的攻擊方式,攻擊者利用系統允許的重試機制,通過多次嘗試重複提交請求,來實現以下目標:
- 繞過安全檢查:例如,發送多次支付請求,試圖重複扣款或重複使用一次性 token。
- 猜測敏感數據:例如,不斷重試不同的憑證或密碼,試圖獲取有效的憑據。
- 利用系統異常:利用系統在某些情況下的異常行為(如高併發導致系統容量耗盡或錯誤處理),達成攻擊目的。
冪等欄位通常是一個唯一識別符(UUID 或類似的值),但可以根據業務需求進行擴展設計。以下是常見的組成方式:
使用 UUID(Universally Unique Identifier)或 GUID(Globally Unique Identifier)。idempotency_key: "4f9e8c3a-9a6b-4d7a-8c3e-123456789abc"
優點:生成簡單且不依賴具體業務邏輯。
缺點:無法反映請求的業務語義,僅適合通用場景。
基於業務的唯一標識符
將業務相關的資訊組合起來,生成冪等欄位。例如:idempotency_key: "order_12345_user_67890"
優點:冪等欄位與業務強相關,便於排查問題。
缺點:欄位設計需要根據具體業務場景定制, 不容易有統一標準.
基於 Hash 的唯一標識符
將請求的核心參數內容(如用戶 ID、訂單 ID、請求時間等)拼接後產生 hash value 作為冪等欄位。idempotency_key: SHA256("user_67890_order_12345_20250124T095200")
優點:減少冪等欄位的長度,並隱藏業務細節。
缺點:需要額外的hash計算,增加了一些處理成本。
基於 Timestamp 的唯一標識符
在唯一標識符中加入時間戳,確保每次請求的冪等欄位不同。Snowflake Id 和 UUIDv7 就基於這種概念.idempotency_key: "4f9e8c3a-9a6b-4d7a-8c3e-123456789abc_20250124T095200"
優點:適合需要頻繁生成冪等欄位的場景。
缺點:client 端如果是使用發出請求時的 timestamp 來產生唯一標識符, 會影響重試機制的有效性。
數字或唯一標識符字串(UUID這類), 各有優缺點.
數字的優點是好比較, payload size小; 缺點是極易被猜測出來範圍.
唯一值字串反過來, 但缺點大部分能用鈔能力解決.