Java接口冪等性,如何重試?
前言
當(dāng)我們寫好一個(gè)項(xiàng)目時(shí),有沒有深深的思考過,如何處理接口冪等性問題呢?今天我們以屈原這句著名詩句“路漫漫其修遠(yuǎn)兮,吾將上下而求索”的精神來探索一下這個(gè)問題。
一、冪等性是什么?
冪等性:簡單來說就是一個(gè)操作多次執(zhí)行的結(jié)果和一次執(zhí)行產(chǎn)生的結(jié)果一致。
二、為什么要冪等性?
答:在計(jì)算機(jī)應(yīng)用中,可能造成網(wǎng)絡(luò)抖動(dòng)、臨時(shí)故障、或者服務(wù)調(diào)用失敗,尤其是分布式系統(tǒng)中,接口調(diào)用失敗更為常見。為了保證服務(wù)的完整性,我們可能會(huì)發(fā)起接口的重試調(diào)用,如果接口不處理冪等,可能會(huì)對(duì)系統(tǒng)造成很大的影響,因此接口的冪等設(shè)計(jì)尤其重要。
如在支付中,如果沒有冪等性,接口的重試可能造成重復(fù)支付。
冪等性和防重是不一樣的,防重不考慮返回值,冪等性要求返回值一樣。
三、使用什么辦法實(shí)現(xiàn)冪等性?
1.insert前先select
通常情況下,在保存數(shù)據(jù)的接口中,我們?yōu)榱朔乐巩a(chǎn)生重復(fù)數(shù)據(jù),一般會(huì)在
insert
前,先根據(jù)name
或code
字段select
一下數(shù)據(jù)。如果該數(shù)據(jù)已存在,則執(zhí)行update
操作,如果不存在,才執(zhí)行insert
操作。
缺點(diǎn): 該方案可能是我們平時(shí)在防止產(chǎn)生重復(fù)數(shù)據(jù)時(shí),使用最多的方案。但是該方案不適用于并發(fā)場(chǎng)景,在并發(fā)場(chǎng)景中,要配合其他方案一起使用,否則同樣會(huì)產(chǎn)生重復(fù)數(shù)據(jù)。我在這里提一下,是為了避免大家踩坑。
2.加悲觀鎖
為了解決這個(gè)問題,可以加悲觀鎖,將用戶A的那行數(shù)據(jù)鎖住,在同一時(shí)刻只允許一個(gè)請(qǐng)求獲得鎖,更新數(shù)據(jù),其他的請(qǐng)求則等待。
缺點(diǎn):不適合冪等性設(shè)計(jì)場(chǎng)景,但是在防重場(chǎng)景中是可以的使用的。
3.加樂觀鎖
為了提升接口性能,我們可以使用樂觀鎖。需要在表中增加一個(gè)
timestamp
或者version
字段。
4.加唯一索引
絕大數(shù)情況下,為了防止重復(fù)數(shù)據(jù)的產(chǎn)生,我們都會(huì)在表中加唯一索引,這是一個(gè)非常簡單,并且有效的方案。
加了唯一索引之后,第一次請(qǐng)求數(shù)據(jù)可以插入成功。但后面的相同請(qǐng)求,插入數(shù)據(jù)時(shí)會(huì)報(bào)Duplicate entry '002' for key 'order.un_code
異常,表示唯一索引有沖突。雖說拋異常對(duì)數(shù)據(jù)來說沒有影響,不會(huì)造成錯(cuò)誤數(shù)據(jù)。但是為了保證接口冪等性,我們需要對(duì)該異常進(jìn)行捕獲,然后返回成功。
5.Redis加分布式鎖
其實(shí)前面介紹過的
加唯一索引
或者加防重表
,本質(zhì)是使用了數(shù)據(jù)庫
的分布式鎖
,也屬于分布式鎖的一種。但由于數(shù)據(jù)庫分布式鎖
的性能不太好,我們可以改用:redis
或zookeeper
。
redis分布式鎖的實(shí)現(xiàn)方式有三種:
1、setNx命令
2、set命令
3、Redission框架
具體步驟:
1、用戶通過瀏覽器發(fā)送請(qǐng)求,服務(wù)器會(huì)收集數(shù)據(jù),并且生成訂單號(hào)code作為唯一業(yè)務(wù)字段。
2、使用redis的set命令,將該訂單code設(shè)置到redis中,同時(shí)設(shè)置超時(shí)時(shí)間。
3、判斷是否設(shè)置成功,如果設(shè)置成功,說明是第一次請(qǐng)求,則數(shù)據(jù)進(jìn)行操作。
4、如果設(shè)置失敗,說明是重復(fù)請(qǐng)求,則直接返回成功。
6.獲取token
除了上述方案之外,還有最后一種使用
token
的方案。該方案跟之前的所有方案都有點(diǎn)不一樣,需要兩次請(qǐng)求才能完成一次業(yè)務(wù)操作。
兩次請(qǐng)求:
1. 第一次請(qǐng)求獲取`token`
2. 第二次請(qǐng)求帶著這個(gè)`token`,完成業(yè)務(wù)操作。
具體步驟:文章來源:http://www.zghlxwxcb.cn/news/detail-499444.html
- 用戶訪問頁面時(shí),瀏覽器自動(dòng)發(fā)起獲取token請(qǐng)求。
- 服務(wù)端生成token,保存到redis中,然后返回給瀏覽器。
- 用戶通過瀏覽器發(fā)起請(qǐng)求時(shí),攜帶該token。
- 在redis中查詢?cè)搕oken是否存在,如果不存在,說明是第一次請(qǐng)求,做則后續(xù)的數(shù)據(jù)操作。
- 如果存在,說明是重復(fù)請(qǐng)求,則直接返回成功。
- 在redis中token會(huì)在過期時(shí)間之后,被自動(dòng)刪除。
總結(jié)
以上就是今天要講的內(nèi)容,本文僅僅簡單介紹了使用什么辦法實(shí)現(xiàn)冪等性,而具體的解決方案還是需要根據(jù)項(xiàng)目自身選擇。文章來源地址http://www.zghlxwxcb.cn/news/detail-499444.html
到了這里,關(guān)于Java接口冪等性,如何重試?的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!