本文由 發(fā)布,轉(zhuǎn)載請(qǐng)注明出處,如有問(wèn)題請(qǐng)聯(lián)系我們! 發(fā)布時(shí)間: 2021-08-22如何保證接口的冪等性?
加載中今日大家來(lái)聊一聊有關(guān)插口的冪等性難題。
什么叫冪等性
說(shuō)白了冪等,便是隨意數(shù)次實(shí)行所造成的危害均與一次實(shí)行的危害同樣。
在 restful 標(biāo)準(zhǔn)中,普遍的要求方法和插口冪等性關(guān)聯(lián)以下:
要求方法 | 實(shí)際操作 | 是不是冪等 |
---|---|---|
GET | 查看數(shù)據(jù)信息 | 是 |
POST | 增加數(shù)據(jù)信息 | 否 |
PUT | 升級(jí)數(shù)據(jù)信息 | 立即升級(jí)為某一值,達(dá)到冪等,如:set a = 1;累積實(shí)際操作的升級(jí),不符合,如:set a = a 1 |
DELETE | 刪掉數(shù)據(jù)信息 | 依據(jù)唯一標(biāo)準(zhǔn)刪掉,達(dá)到冪等;不然,不符合,冪等,例如:依據(jù)某一標(biāo)準(zhǔn)刪掉一批數(shù)據(jù)信息后,又增加了一條達(dá)到該標(biāo)準(zhǔn)的數(shù)據(jù)信息,又實(shí)行了一次刪掉,那麼便會(huì)刪掉掉增加的這一條數(shù)據(jù)信息 |
怎么會(huì)造成插口冪等性難題
在計(jì)算機(jī)技術(shù)中,很有可能碰到網(wǎng)絡(luò)抖動(dòng),臨時(shí)性常見(jiàn)故障,或是服務(wù)項(xiàng)目啟用不成功,尤其是分布式架構(gòu)中,插口啟用不成功更加普遍。為了更好地確保服務(wù)項(xiàng)目的一致性,大家很有可能會(huì)進(jìn)行插口的再試啟用,假如插口不解決冪等,很有可能系統(tǒng)對(duì)導(dǎo)致非常大的危害,因而插口的冪等設(shè)計(jì)方案特別是在至關(guān)重要。
針對(duì)業(yè)務(wù)流程中必須考慮到冪等性的地區(qū)一般全是插口的反復(fù)要求,反復(fù)要求就是指同一個(gè)要求由于一些緣故被數(shù)次遞交。造成這類(lèi)狀況的產(chǎn)生有下列幾類(lèi)普遍的情景:
-
前面反復(fù)遞交:客戶(hù)在表單提交的情況下,很有可能會(huì)因?yàn)榫W(wǎng)絡(luò)不穩(wěn)定沒(méi)有立即作出操作成功回應(yīng),導(dǎo)致客戶(hù)覺(jué)得沒(méi)有取得成功遞交,隨后一直點(diǎn)提交按鈕,這時(shí)候便會(huì)產(chǎn)生反復(fù)表單提交要求。
-
插口請(qǐng)求超時(shí)再試:第三方啟用插口情況下,為了更好地請(qǐng)求超時(shí)等異?,F(xiàn)象導(dǎo)致的要求不成功,都是會(huì)加上再試體制,造成一個(gè)要求遞交數(shù)次。
-
信息反復(fù)消費(fèi):當(dāng)應(yīng)用 MQ 消息中間件情況下,假如產(chǎn)生消息中間件發(fā)生不正確未立即遞交消費(fèi)信息內(nèi)容,造成產(chǎn)生反復(fù)消費(fèi)。
冪等性解決方法
那大家應(yīng)當(dāng)能如何確保插口的冪等性呢?
能夠 思索一下,第一種情景下,即然是客戶(hù)反復(fù)遞交造成的,那我們可以想辦法讓客戶(hù)沒(méi)法反復(fù)遞交。
計(jì)劃方案一:前面操縱
在前面做阻攔,例如按鍵點(diǎn)一下一次以后就置灰或是掩藏。可是通常前面并不靠譜,或是得后面解決才更安心。
計(jì)劃方案二:Token體制
客戶(hù)進(jìn)到表格網(wǎng)頁(yè)頁(yè)面最先啟用后臺(tái)管理插口獲得 token 并存進(jìn) redis,當(dāng)客戶(hù)表單提交時(shí)將 token 也做為入?yún)?,后面先刪掉 redis 中的 token,刪掉取得成功則儲(chǔ)存表格數(shù)據(jù)信息,不成功則提醒客戶(hù)反復(fù)遞交。
這兒為什么不先分辨 redis 是不是存有這一 token 再刪掉,是由于要確保實(shí)際操作的原子性,極端化狀況下,第一個(gè)要求查看到 redis 中存有這一 token,還不等他刪掉,第二個(gè)要求進(jìn)去,也查看到 redis 中存有這一 token,那麼依然會(huì)導(dǎo)致反復(fù)遞交的難題。
token 體制必須先要求獲得 token 的插口,在有一些狀況下很顯著并不適合。大家絕大多數(shù)要求全是要落入數(shù)據(jù)庫(kù)查詢(xún)的,因此 我們可以從數(shù)據(jù)庫(kù)查詢(xún)下手。
計(jì)劃方案三、唯一索引
這類(lèi)計(jì)劃方案就比較好了解了,應(yīng)用唯一索引能夠 防止臟數(shù)據(jù)的加上,當(dāng)插進(jìn)反復(fù)數(shù)據(jù)信息時(shí)數(shù)據(jù)庫(kù)查詢(xún)會(huì)拋出現(xiàn)異常,確保了數(shù)據(jù)信息的唯一性。唯一索引能夠 適用插進(jìn)、升級(jí)、刪掉業(yè)務(wù)流程實(shí)際操作。
計(jì)劃方案四、悲觀(guān)鎖
這兒常說(shuō)的悲觀(guān)鎖是根據(jù)數(shù)據(jù)庫(kù)查詢(xún)方面的,在讀取數(shù)據(jù)時(shí)開(kāi)展上鎖,當(dāng)與此同時(shí)有好幾個(gè)反復(fù)要求時(shí),別的要求都沒(méi)法開(kāi)展實(shí)際操作。悲觀(guān)鎖只適用升級(jí)實(shí)際操作。
// 比如
select name from t_goods where id=1 for update;
留意:id 字段名一定如果外鍵約束或是唯一索引,要不然會(huì)鎖定一整張表,這也是會(huì)死尸的。悲觀(guān)鎖應(yīng)用時(shí)一般隨著事務(wù)管理一起應(yīng)用,數(shù)據(jù)信息鎖住時(shí)間很有可能會(huì)較長(zhǎng),依據(jù)具體情況采用。
在要求量較為大的狀況下,應(yīng)用悲觀(guān)鎖顯著不適合,此刻就到樂(lè)觀(guān)鎖出場(chǎng)了。
計(jì)劃方案五、樂(lè)觀(guān)鎖
能夠 根據(jù)版本信息完成,為表提升一個(gè) version 字段名,當(dāng)數(shù)據(jù)信息必須升級(jí)時(shí),先去數(shù)據(jù)庫(kù)查詢(xún)里獲得這時(shí)的version版本信息。
select version from t_goods where id=1
升級(jí)數(shù)據(jù)信息時(shí)最先要比照版本信息,如果不相同表明早已有別的的要求去升級(jí)數(shù)據(jù)信息了,提醒更新失敗。
update t_goods set count=count 1,version=version 1 where version=#{version}
也有一種是根據(jù)狀態(tài)機(jī)完成的,實(shí)際上也是開(kāi)朗鎖的原理。這類(lèi)方式合適在有情況運(yùn)轉(zhuǎn)的狀況下,例如訂單信息的建立和支付,訂單信息的建立毫無(wú)疑問(wèn)是在支付以前,這時(shí)候我們可以根據(jù)在設(shè)計(jì)方案狀態(tài)字段時(shí),應(yīng)用 int 種類(lèi),而且根據(jù)值種類(lèi)的尺寸來(lái)完成冪等性。
update t_goods set status=#{status} where id=1 and status<#{status}
一樣,樂(lè)觀(guān)鎖也只適用升級(jí)實(shí)際操作。
計(jì)劃方案六、分布式鎖
有時(shí)大家的業(yè)務(wù)流程不僅是實(shí)際操作數(shù)據(jù)庫(kù)查詢(xún),也可能是發(fā)送信息、信息這些,那數(shù)據(jù)庫(kù)查詢(xún)方面的鎖就不宜了。這類(lèi)狀況下就需要考慮到編碼方面的鎖了,而 java 的內(nèi)置的鎖在分布式系統(tǒng)群集布署的情景下并不適合,那麼就可以選用分布式鎖來(lái)完成(Redis 或 Zookeeper)。
拿 Redis 分布式鎖舉例說(shuō)明,例如一個(gè)訂單信息進(jìn)行付款要求,支付平臺(tái)會(huì)去 Redis 緩存文件中查看是不是存有該訂單編號(hào)的 Key,假如不會(huì)有,則以 Key 為訂單編號(hào)向 Redis 插進(jìn)。查訂單是不是早已付款,要是沒(méi)有則開(kāi)展付款,付款進(jìn)行后刪掉該訂單編號(hào)的Key。根據(jù) Redis 保證了分布式鎖,僅有此次訂單支付要求進(jìn)行,下一次要求才可以進(jìn)去。自然這兒必須設(shè)定一個(gè)Key 的到期時(shí)間,在產(chǎn)生出現(xiàn)異常的情況下還需要留意刪掉 Redis 的 Key。
匯總
插口的冪等性是一個(gè)很普遍的難題,必須依據(jù)實(shí)際業(yè)務(wù)場(chǎng)景的不一樣,挑選適合的解決方法。
END
以往強(qiáng)烈推薦
你務(wù)必掌握的分布式事務(wù)解決方法
就這?分布式系統(tǒng) ID 發(fā)號(hào)器實(shí)戰(zhàn)演練
略知一二策略模式之工廠(chǎng)模式
就這?Spring 事務(wù)管理無(wú)效情景及解決方法
就這?一篇文章使你了解 Spring 事務(wù)管理
文中來(lái)源于博客園,創(chuàng)作者:靚妹聊程序編寫(xiě),轉(zhuǎn)截請(qǐng)標(biāo)明全文連接:https://www.cnblogs.com/liangzaiit/p/15171618.html