javascript
springboot token_Springboot接口幂等性基于token实现方案
什么是接口冪等
冪等(idempotent、idempotence)是一個數(shù)學與計算機學概念,常見于抽象代數(shù)中,即f(f(x)) = f(x).簡單的來說就是一個操作多次執(zhí)行產生的結果與一次執(zhí)行產生的結果一致。有些系統(tǒng)操作天生就具有冪等性例如數(shù)據(jù)庫的select語句,但更多時候是需要程序員來做保證的,尤其是在分布式系統(tǒng)環(huán)境中,接口能不能做到保證冪等性對系統(tǒng)的影響可能是非常大的,例如很常見的支付下單等場景,由于分布式環(huán)境中網絡的復雜性,用戶誤操作,網絡抖動,消息重復,服務超時導致業(yè)務自動重試等等各種情況都可能會使線上數(shù)據(jù)產生了不一致,造成生產事故。
實現(xiàn)方案
1、查詢操作:查詢一次和查詢多次,在數(shù)據(jù)不變的情況下,查詢結果是一樣的。select是天然的冪等操作;2、刪除操作:刪除操作也是冪等的,刪除一次和多次刪除都是把數(shù)據(jù)刪除。(注意可能返回結果不一樣,刪除的數(shù)據(jù)不存在,返回0,刪除的數(shù)據(jù)多條,返回結果多個) ;3、唯一索引:利用數(shù)據(jù)庫新增臟數(shù)據(jù)。比如:支付寶的資金賬戶,支付寶也有用戶賬戶,每個用戶只能有一個資金賬戶,怎么防止給用戶創(chuàng)建資金賬戶多個,那么給資金賬戶表中的用戶ID加唯一索引,所以一個用戶新增成功一個資金賬戶記錄。要點:唯一索引或唯一組合索引來防止新增數(shù)據(jù)存在臟數(shù)據(jù)(當表存在唯一索引,并發(fā)時新增報錯時,再查詢一次就可以了,數(shù)據(jù)應該已經存在了,返回結果即可);4、token機制:防止頁面重復提交。采用token加redis或token加jvm內存。處理流程:1. 數(shù)據(jù)提交前要向服務的申請token,token放到redis或jvm內存,token有效時間;2. 提交后后臺校驗token,同時刪除token,生成新的token返回。token特點:要申請,一次有效性,可以限流。注意:redis要用刪除操作來判斷token,刪除成功代表token校驗通過,如果用select+delete來校驗token,存在并發(fā)問題,不建議使用;5、分布式鎖:如果是分布式系統(tǒng)的話,構建全局唯一索引會比較困難,比如唯一性的字段就沒有辦法確定。這時候可以引入分布式鎖,通過第三方的系統(tǒng)(Redis或Zookeeper),在業(yè)務系統(tǒng)插入數(shù)據(jù)或者更新數(shù)據(jù)前,需要先獲取分布式鎖,然后才能做操作,操作完成之后就釋放鎖。這樣其實是把單機系統(tǒng)里面多線程并發(fā)鎖的思路引入了多個系統(tǒng)的場景,也就是分布式系統(tǒng)中的解決思路。要點:某個長流程處理過程要求不能并發(fā)執(zhí)行,可以在流程執(zhí)行之前根據(jù)某個標志(用戶ID+后綴等)獲取分布式鎖,其他流程執(zhí)行時獲取鎖就會失敗,也就是同一時間該流程只能有一個能執(zhí)行成功,執(zhí)行完成后,釋放分布式鎖(分布式鎖要第三方系統(tǒng)提供)。6、select + insert:在設計單據(jù)相關的業(yè)務,或者是任務相關的業(yè)務,肯定會涉及到狀態(tài)機(狀態(tài)變更圖)。簡單理解,就是業(yè)務單據(jù)上面有個狀態(tài)的字段,狀態(tài)在不同的情況下會發(fā)生變更,一般情況下存在有限狀態(tài)機。這時候,如果狀態(tài)機已經處于下一個狀態(tài),這時候來了一個上一個狀態(tài)的變更,理論上是不能夠變更的,這樣的話,保證了有限狀態(tài)機的冪等。注意:訂單等單據(jù)類業(yè)務,存在很長的狀態(tài)流轉,一定要深刻理解狀態(tài)機,對業(yè)務系統(tǒng)設計能力提高有很大幫助。
基于token+Redis的實現(xiàn)方案
環(huán)境:springboot2.2.11.RELEASE + Redis
- pom.xml 依賴
- 自定義注解類,有該注解的需要驗證token是否有效
- 攔截器定義,攔截請求方法進行token有效性驗證
- WebConfig 配置攔截器
- Controller 測試
business 方法加入了@ApiIdempotent注解,表示該方法需要進行token驗證是否有效的請求
整個請求流程要先獲取token,然后將得到的token放入header中或者請求參數(shù)中。
測試:
獲取token:
請求業(yè)務方法將獲取的token 添加到header中
再次請求:
每次請求token的驗證是通過刪除token進行的,所以當?shù)诙卧僬埱髸r,redis中已經沒有了token所以這里就提示:重復提交了。
完畢!!!
給個關注,轉發(fā),謝謝
SpringBoot RabbitMQ消息可靠發(fā)送與接收
SpringBoot中使用Cache及JSR107的使用
SpringBoot開發(fā)自己的Starter
SpringBoot開發(fā)自己的@Enable功能
Java線上CPU100% 問題排查
Restful API設計規(guī)范
SpringCloud Nacos 服務動態(tài)配置
SpringCloud Nacos 服務消費者
SpringCloud Nacos 服務提供者
SpringCloud Alibaba 之 Nacos 服務
Spring Cloud Nacos 開啟權限驗證
SpringCloud Nacos 整合feign
SpringCloud Hystrix實現(xiàn)資源隔離應用
Alibaba Sentinel動態(tài)規(guī)則(Nacos數(shù)據(jù)源)
SpringCloud zuul 動態(tài)網關配置
總結
以上是生活随笔為你收集整理的springboot token_Springboot接口幂等性基于token实现方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sql order by 降序_数仓面试
- 下一篇: python与tensorflow的关系