Spring Boot接口冪等插件用法示例解析
冪等概述
冪等性原本是數(shù)學(xué)上的概念,即使公式:f(x)=f(f(x)) 能夠成立的數(shù)學(xué)性質(zhì)。用在編程領(lǐng)域,則意為對同一個系統(tǒng),使用同樣的條件,一次請求和重復(fù)的多次請求對系統(tǒng)資源的影響是一致的。
冪等性是分布式系統(tǒng)設(shè)計(jì)中十分重要的概念,具有這一性質(zhì)的接口在設(shè)計(jì)時總是秉持這樣的一種理念:調(diào)用接口發(fā)生異常并且重復(fù)嘗試時,總是會造成系統(tǒng)所無法承受的損失,所以必須阻止這種現(xiàn)象的發(fā)生。
實(shí)現(xiàn)冪等的方式很多,目前基于請求令牌機(jī)制適用范圍較廣。其核心思想是為每一次操作生成一個唯一性的憑證,也就是 token。一個 token 在操作的每一個階段只有一次執(zhí)行權(quán),一旦執(zhí)行成功則保存執(zhí)行結(jié)果。對重復(fù)的請求,返回同一個結(jié)果(報錯)等。參考《冪等性淺談》
冪等處理實(shí)現(xiàn)加入依賴
配置 Redis
鏈接默認(rèn)情況下,可以不配置。理論是支持 redisson-spring-boot-starter 全部配置
spring: redis: host: 127.0.0.1 port: 6379
接口
@Idempotent(key = "#key", expireTime = 10, info = "請勿重復(fù)查詢") @GetMapping("/test") public String test(String key) { return "success"; }
測試10 個獨(dú)立線程請求
執(zhí)行查看結(jié)果,10 個請求只會有一個成功
查看后臺異常報錯,9 個異常報錯滿足預(yù)期
idempotent 注解說明
- key: 冪等操作的唯一標(biāo)識,使用 spring el 表達(dá)式 用#來引用方法參數(shù) 。 可為空則取當(dāng)前 url + args 做請求的唯一標(biāo)識
- expireTime: 有效期 默認(rèn):1 有效期要大于程序執(zhí)行時間,否則請求還是可能會進(jìn)來
- timeUnit: 時間單位 默認(rèn):s (秒)
- info: 冪等失敗提示信息,可自定義
- delKey: 是否在業(yè)務(wù)完成后刪除 key true:刪除 false:不刪除
冪等處理設(shè)計(jì)原理
1.請求開始前,根據(jù) key 查詢 查到結(jié)果:報錯 未查到結(jié)果:存入 key-value-expireTime key=ip+url+args
2.請求結(jié)束后,直接刪除 key 不管 key 是否存在,直接刪除 是否刪除,可配置
3.expireTime 過期時間,防止一個請求卡死,會一直阻塞,超過過期時間,自動刪除 過期時間要大于業(yè)務(wù)執(zhí)行時間,需要大概評估下;
4.此方案直接切的是接口請求層面。
5.過期時間需要大于業(yè)務(wù)執(zhí)行時間,否則業(yè)務(wù)請求 1 進(jìn)來還在執(zhí)行中,前端未做遮罩,或者用戶跳轉(zhuǎn)頁面后再回來做重復(fù)請求 2,在業(yè)務(wù)層面上看,結(jié)果依舊是不符合預(yù)期的。
6.建議 delKey = false。即使業(yè)務(wù)執(zhí)行完,也不刪除 key,強(qiáng)制鎖 expireTime 的時間。預(yù)防 5 的情況發(fā)生。
7.實(shí)現(xiàn)思路:同一個請求 ip 和接口,相同參數(shù)的請求,在 expireTime 內(nèi)多次請求,只允許成功一次。
8.頁面做遮罩,數(shù)據(jù)庫層面的唯一索引,先查詢再添加,等處理方式應(yīng)該都處理下。
9.此注解只用于冪等,不用于鎖,100 個并發(fā)這種壓測,會出現(xiàn)問題,在這種場景下也沒有意義,實(shí)際中用戶也不會出現(xiàn) 1s 或者 3s 內(nèi)手動發(fā)送了 50 個或者 100 個重復(fù)請求,或者弱網(wǎng)下有 100 個重復(fù)請求;
總結(jié)
pig-mesh/idempotent-spring-boot-starter
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
最新hadoop安裝教程及hadoop的命令使用(親測可用)
這篇文章主要介紹了最新hadoop安裝教程(親測可用),本文主要講解了如何安裝hadoop、使用hadoop的命令及遇到的問題解決,需要的朋友可以參考下2022-06-06Java 為什么要避免使用finalizer和Cleaner
這篇文章主要介紹了Java 為什么要避免使用finalizer和Cleaner,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下2021-03-03解決springboot+activemq啟動報注解錯誤的問題
這篇文章主要介紹了解決springboot+activemq啟動報注解錯誤的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07詳解springboot+atomikos+druid?數(shù)據(jù)庫連接失效分析
本文主要介紹了springboot+atomikos+druid?數(shù)據(jù)庫連接失效分析,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02文件上傳SpringBoot后端MultipartFile參數(shù)報空問題的解決辦法
這篇文章主要介紹了文件上傳SpringBoot后端MultipartFile參數(shù)報空問題的解決辦法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11Elasticsearch?Recovery索引分片分配詳解
這篇文章主要為大家介紹了關(guān)于Elasticsearch的Recovery索引分片分配詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>2022-04-04