1. 程式人生 > >redis設計冪等介面

redis設計冪等介面

冪等:

冪等性是系統的介面對外一種承諾(而不是實現), 承諾只要呼叫介面成功, 外部多次呼叫對系統的影響是一致的. 宣告為冪等的介面會認為外部呼叫失敗是常態, 並且失敗之後必然會有重試

舉個例子:
有一個訂單系統,對外提供了一個處理介面,
如果有個訂單001是要扣除使用者的100塊錢,那麼訂單001被多次呼叫,
也只會處理成功一次,也就是隻會扣除使用者100塊。
也可以理解為去除重複呼叫

訂單的狀態:

a) 無記錄
b) 正在被處理
c) 處理成功

我們需要考慮多種情況:

情況1:

a) a執行緒開始處理訂單001
b) a執行緒處理訂單001成功
c) a執行緒記錄訂單001處理成功

情況2:
a) a執行緒開始處理訂單001
b) a執行緒處理訂單001失敗,回滾

c) a執行緒刪除訂單001的記錄

情況3:
a) a執行緒已成功處理訂單001
b) b執行緒開始處理訂單001,發現訂單001已經被成功處理,放棄此次處理

情況4:
a) a執行緒開始處理訂單001,正在處理中
b) b執行緒開始處理訂單001,發現訂單001正在被處理且未超時,放棄此次處理

情況5:
a) a執行緒開始處理訂單001,且超時了釋放了訂單001的狀態
b) b執行緒開始處理訂單001,發現訂單001無人處理,那麼鎖定訂單001開始處理


我們用redis來設計處理的冪等性,但是需要注意的是,這裡冪等性的有效期依賴redis的key的生命週期:
a) 正在處理,假設5分鐘則認為處理超時(這個值需要根據程式的處理邏輯的超時時間設定)
SET 訂單號                         時間戳                過期時間

SET 1893505609317740 1466849127 EX 300 NX

b) 成功處理,利用SET的時間戳控制設定權
SET 訂單號                       成功  過期時間
SET 1893505609317740 0 EX 86400 XX

c) 刪除訂單,只允許建立者刪除,利用SET的時間戳控制刪除權

DEL 1893505609317740

小結:

這種設計依然有缺陷,但是能保證大部分的訂單是冪等性的

首先要保證redis是高可用,

其次訂單的處理過期時間很重要,不能隨意設定,必須根據程式處理流程推理出來,

其次redis的儲存空間也影響了訂單的狀態儲存多久。