天天看點

Archi - 幂等問題

1. 什麼是幂等問題?

舉個最簡單的例子,那就是支付,使用者購買商品後支付,支付扣款成功,但是傳回結果的時候網絡異常,此時錢已經扣了,使用者再次點選按鈕,此時會進行第二次扣款,傳回結果成功,使用者查詢餘額發現多扣了錢,流水記錄也變成了兩條。

2. 怎麼保證幂等性?

通過代碼邏輯判斷實作接口幂等性,隻能針對一些滿足判斷的邏輯實作,具有一定局限性。

原始版本

boolean pay(int accountid,BigDecimal amount) //用于付款,扣除使用者的

Archi - 幂等問題

這種情況下,支付系統已經扣款,但是訂單系統因為網絡原因,沒有擷取到确切的結果,是以訂單系統需要重試。由上圖可見,支付系統并沒有做到接口的幂等性,訂單系統第一次調用和第二次調用,使用者分别被扣了兩次錢,不符合幂等性原則(同一個訂單,無論是調用了多少次,使用者都隻會扣款一次)。如果需要支援幂等性,付款接口需要修改為以下接口:

幂等版本

boolean pay(int orderId,int accountId,BigDecimal amount)

Archi - 幂等問題

通過orderId來标定訂單的唯一性,付款系統隻要檢測到訂單已經支付過,則第二次調用不會扣款而會直接傳回結果

使用token機制實作接口幂等性,通用性強的實作方法。

token機制實作步驟:

生成全局唯一的token,token放到redis或jvm記憶體,token會在頁面跳轉時擷取.存放到pageScope中,支付請求送出先擷取token

送出後背景校驗token,執行送出邏輯,送出成功同時删除token,生成新的token更新redis ,這樣當第一次送出後token更新了,頁面再次送出攜帶的token是已删除的token背景驗證會失敗不讓送出

token特點: 要申請,一次有效性,可以限流

注意: redis要用删除操作來判斷token,删除成功代表token校驗通過,如果用select+delete來校驗token,存在并發問題,不建議使用

Distributed - 分布式鎖

參考文獻

接口幂等性

繼續閱讀