基于Redis&MySQL介面冪等性設計
欲把相思說似誰,淺情人不知,
1、冪等
冪等性即多次呼叫介面或方法不會改變業務狀態,可以保證重復呼叫的結果和單次呼叫的結果一致,
2、冪等使用場景
前端重復提交
用戶注冊、創建商品、提交訂單、轉賬、支付等操作,前端都會提交一些資料給后臺服務,后臺需要根據用戶提交的資料在資料庫中創建記錄,如果用戶不小心多點了幾次,后端收到了好幾次提交,這時就會在資料庫中重復創建了多條記錄,這就是介面沒有冪等性帶來的bug,
介面超時重試
對于給第三方呼叫的介面,有可能會因為網路原因而呼叫失敗,這種情況一般在設計的時候會對介面呼叫加上失敗重試的機制,如果第一次呼叫已經執行了一半時發生了網路例外,這時再次呼叫時就會因為臟資料的存在而出現呼叫例外,
訊息重復消費
在使用訊息中間件來處理訊息佇列,且手動 ack 確認訊息被正常消費時,如果消費者突然斷開連接,那么已經執行了一半的訊息會重新放回佇列,
當訊息被其他消費者重新消費時,如果沒有冪等性,就會導致訊息重復消費引起結果例外如資料庫重復資料等,
3、解決方案
基于Token
通過token 機制實作介面的冪等性,是一種比較通用性的實作方法,

具體流程步驟:
-
客戶端會先發送一個請求去獲取 token,服務端會生成一個全域唯一的 ID 作為 token 保存在 redis 中,同時把這個 ID 回傳給客戶端;
-
客戶端第二次呼叫業務請求的時候必須攜帶這個 token;
-
服務端會校驗這個 token,如果校驗成功,則執行業務,并洗掉 redis 中的 token;
-
如果校驗失敗,說明 redis 中已經沒有對應的 token,則表示重復操作,直接回傳指定的結果給客戶端,
基于MySQL
基于MySQL實作方式是利用了 mysql 唯一索引的特性,

具體流程步驟:
-
建立一張去重表,其中某個欄位需要建立唯一索引,如訂單ID,用戶ID;
-
客戶端去請求服務端,服務端會將這次請求的一些資訊插入這張去重表中;
-
因為表中某個欄位帶有唯一索引,如果插入成功,證明表中沒有這次請求的資訊,則執行后續的業務邏輯;
-
如果插入失敗,則代表已經執行過當前請求,直接回傳,
基于Redis
基于Redis是利用了 SETNX 命令實作的,

SETNX key value:將 key 的值設為 value ,當且僅當 key 不存在,若給定的 key 已經存在,則 SETNX 不做任何動作,
該命令在設定成功時回傳 1,設定失敗時回傳 0,
具體流程步驟:
-
客戶端先請求服務端,會拿到一個能代表這次請求業務的唯一欄位;
-
將該欄位以 SETNX 的方式存入 redis 中,并根據業務設定相應的超時時間;
-
如果設定成功,證明這是第一次請求,則執行后續的業務邏輯;
-
如果設定失敗,則代表已經執行過當前請求,直接回傳,
欲把相思說似誰
淺情人不知
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/421624.html
標籤:其他
