冪等概述
-
冪等性原本是數學上的概念,即使公式:f(x)=f(f(x)) 能夠成立的數學性質,用在編程領域,則意為對同一個系統,使用同樣的條件,一次請求和重復的多次請求對系統資源的影響是一致的,
-
冪等性是分布式系統設計中十分重要的概念,具有這一性質的介面在設計時總是秉持這樣的一種理念:呼叫介面發生例外并且重復嘗試時,總是會造成系統所無法承受的損失,所以必須阻止這種現象的發生,
-
實作冪等的方式很多,目前基于請求令牌機制適用范圍較廣,其核心思想是為每一次操作生成一個唯一性的憑證,也就是 token,一個 token 在操作的每一個階段只有一次執行權,一旦執行成功則保存執行結果,對重復的請求,回傳同一個結果(報錯)等,參考《冪等性淺談》
冪等處理實作
加入依賴
<dependency>
<groupId>com.pig4cloud.plugin</groupId>
<artifactId>idempotent-spring-boot-starter</artifactId>
<version>0.0.1</version>
</dependency>
配置 Redis 鏈接
- 默認情況下,可以不配置,理論是支持 redisson-spring-boot-starter 全部配置
spring:
redis:
host: 127.0.0.1
port: 6379
介面
@Idempotent(key = "#key", expireTime = 10, info = "請勿重復查詢")
@GetMapping("/test")
public String test(String key) {
return "success";
}
測驗
- 10 個獨立執行緒請求

-
執行查看結果,10 個請求只會有一個成功

-
查看后臺例外報錯,9 個例外報錯滿足預期

idempotent 注解說明
-
key: 冪等操作的唯一標識,使用 spring el 運算式 用#來參考方法引數 , 可為空則取當前 url + args 做請求的唯一標識
-
expireTime: 有效期 默認:1 有效期要大于程式執行時間,否則請求還是可能會進來
-
timeUnit: 時間單位 默認:s (秒)
-
info: 冪等失敗提示資訊,可自定義
-
delKey: 是否在業務完成后洗掉 key true:洗掉 false:不洗掉
冪等處理設計原理
流程設計參考
-
1.請求開始前,根據 key 查詢 查到結果:報錯 未查到結果:存入 key-value-expireTime key=ip+url+args
-
2.請求結束后,直接洗掉 key 不管 key 是否存在,直接洗掉 是否洗掉,可配置
-
3.expireTime 過期時間,防止一個請求卡死,會一直阻塞,超過過期時間,自動洗掉 過期時間要大于業務執行時間,需要大概評估下;
-
4.此方案直接切的是介面請求層面,
-
5.過期時間需要大于業務執行時間,否則業務請求 1 進來還在執行中,前端未做遮罩,或者用戶跳轉頁面后再回來做重復請求 2,在業務層面上看,結果依舊是不符合預期的,
-
6.建議 delKey = false,即使業務執行完,也不洗掉 key,強制鎖 expireTime 的時間,預防 5 的情況發生,
-
7.實作思路:同一個請求 ip 和介面,相同引數的請求,在 expireTime 內多次請求,只允許成功一次,
-
8.頁面做遮罩,資料庫層面的唯一索引,先查詢再添加,等處理方式應該都處理下,
-
9.此注解只用于冪等,不用于鎖,100 個并發這種壓測,會出現問題,在這種場景下也沒有意義,實際中用戶也不會出現 1s 或者 3s 內手動發送了 50 個或者 100 個重復請求,或者弱網下有 100 個重復請求;
總結
-
pig-mesh/pig
-
pig-mesh/idempotent-spring-boot-starter
專案推薦: Spring Cloud 、Spring Security OAuth2的RBAC權限管理系統 歡迎關注
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/207969.html
標籤:其他
下一篇:pycharm雙擊無法啟動
