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