基於Redis&MySQL接口冪等性設計

基於Redis&MySQL接口冪等性設計

 

      欲把相思說似誰,淺情人不知。

 

1、冪等

冪等性即多次調用接口或方法不會改變業務狀態,可以保證重複調用的結果和單次調用的結果一致。

2、冪等使用場景

前端重複提交

用戶註冊、創建商品、提交訂單、轉賬、支付等操作,前端都會提交一些數據給後臺服務,後臺需要根據用戶提交的數據在數據庫中創建記錄。如果用戶不小心多點了幾次,後端收到了好幾次提交,這時就會在數據庫中重複創建了多條記錄。這就是接口沒有冪等性帶來的bug。

接口超時重試

對於給第三方調用的接口,有可能會因爲網絡原因而調用失敗,這種情況一般在設計的時候會對接口調用加上失敗重試的機制,如果第一次調用已經執行了一半時發生了網絡異常,這時再次調用時就會因爲髒數據的存在而出現調用異常。

消息重複消費
在使用消息中間件來處理消息隊列,且手動 ack 確認消息被正常消費時。如果消費者突然斷開連接,那麼已經執行了一半的消息會重新放回隊列。
當消息被其他消費者重新消費時,如果沒有冪等性,就會導致消息重複消費引起結果異常如數據庫重複數據等。

3、解決方案

基於Token

通過token 機制實現接口的冪等性,是一種比較通用性的實現方法。

具體流程步驟:

  1. 客戶端會先發送一個請求去獲取 token,服務端會生成一個全局唯一的 ID 作爲 token 保存在 redis 中,同時把這個 ID 返回給客戶端;

  2. 客戶端第二次調用業務請求的時候必須攜帶這個 token;

  3. 服務端會校驗這個 token,如果校驗成功,則執行業務,並刪除 redis 中的 token;

  4. 如果校驗失敗,說明 redis 中已經沒有對應的 token,則表示重複操作,直接返回指定的結果給客戶端。

基於MySQL

基於MySQL實現方式是利用了 mysql 唯一索引的特性。

具體流程步驟:

  1. 建立一張去重表,其中某個字段需要建立唯一索引,如訂單ID,用戶ID;

  2. 客戶端去請求服務端,服務端會將這次請求的一些信息插入這張去重表中;

  3. 因爲表中某個字段帶有唯一索引,如果插入成功,證明表中沒有這次請求的信息,則執行後續的業務邏輯;

  4. 如果插入失敗,則代表已經執行過當前請求,直接返回。

基於Redis

基於Redis是利用了 SETNX 命令實現的。

SETNX key value:將 key 的值設爲 value ,當且僅當 key 不存在。若給定的 key 已經存在,則 SETNX 不做任何動作。

該命令在設置成功時返回 1,設置失敗時返回 0。

具體流程步驟:

  1. 客戶端先請求服務端,會拿到一個能代表這次請求業務的唯一字段;

  2. 將該字段以 SETNX 的方式存入 redis 中,並根據業務設置相應的超時時間;

  3. 如果設置成功,證明這是第一次請求,則執行後續的業務邏輯;

  4. 如果設置失敗,則代表已經執行過當前請求,直接返回。

 

 

 

欲把相思說似誰

          淺情人不知

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章