日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁(yè) > 科技  > 軟件

前任開發(fā)在代碼里下毒,支付下單居然沒(méi)加冪等

來(lái)源: 責(zé)編: 時(shí)間:2024-01-16 17:34:10 276觀看
導(dǎo)讀故事又是一個(gè)風(fēng)和日麗美好的一天,小貓戴著耳機(jī),安逸地聽著音樂(lè),擼著代碼,這種沒(méi)有會(huì)議的日子真的是巴適得板。不料禍從天降,組長(zhǎng)火急火燎地跑過(guò)來(lái)找到了小貓?!翱炫挪橐幌?,目前有A公司用戶反饋積分被多扣了”。小貓回憶了

故事

又是一個(gè)風(fēng)和日麗美好的一天,小貓戴著耳機(jī),安逸地聽著音樂(lè),擼著代碼,這種沒(méi)有會(huì)議的日子真的是巴適得板。yDI28資訊網(wǎng)——每日最新資訊28at.com

不料禍從天降,組長(zhǎng)火急火燎地跑過(guò)來(lái)找到了小貓?!翱炫挪橐幌拢壳坝蠥公司用戶反饋積分被多扣了”。yDI28資訊網(wǎng)——每日最新資訊28at.com

小貓回憶了一下“不對(duì)啊,這接口我也沒(méi)動(dòng)過(guò)啊,前幾天對(duì)外平臺(tái)的老六直接找我要個(gè)支付接口,我就給他了的,以前的代碼,我都沒(méi)有動(dòng)過(guò)的......”。yDI28資訊網(wǎng)——每日最新資訊28at.com

于是小貓一邊疑惑一邊翻看著以前的代碼,越看臉色越差......yDI28資訊網(wǎng)——每日最新資訊28at.com

yDI28資訊網(wǎng)——每日最新資訊28at.com

小貓做的是一個(gè)標(biāo)準(zhǔn)的積分兌換商城,以前和客戶合作的時(shí)候,客戶直接用的是小貓單位自己定制的h5頁(yè)面。這次合作了一家公司有點(diǎn)特殊,由于公司想要定制化自己個(gè)性化的H5,加上本身A公司自己有開發(fā)能力,所以經(jīng)過(guò)討論就以接口的方式直接將相關(guān)接口給出去,A客戶H5開發(fā)完成之后自己來(lái)對(duì)接。yDI28資訊網(wǎng)——每日最新資訊28at.com

慢慢地,原因也水落石出,之前好好的業(yè)務(wù)一直沒(méi)有問(wèn)題是因?yàn)樯坛堑谋旧鞨5頁(yè)面做了防重復(fù)提交,由于量小,并且一般對(duì)接方式用的都是純H5,所以都沒(méi)有什么問(wèn)題,然后這次是直接將接口給出去了,完了接口居然沒(méi)有加冪等......yDI28資訊網(wǎng)——每日最新資訊28at.com

小貓?zhí)蓸專瑪?shù)據(jù)訂正當(dāng)然是少不了了,事故報(bào)告當(dāng)然也少不了了。yDI28資訊網(wǎng)——每日最新資訊28at.com

正所謂前人挖坑,后人遭殃,前人鍋后人背。yDI28資訊網(wǎng)——每日最新資訊28at.com

聊聊冪等

1.接口冪等梗概

這個(gè)案例其實(shí)就是一個(gè)典型的接口冪等案例。那么老貓就和大家從以下幾個(gè)方面好好剖析一下接口冪等吧。yDI28資訊網(wǎng)——每日最新資訊28at.com

yDI28資訊網(wǎng)——每日最新資訊28at.com

2.什么是接口冪等

比較專業(yè)的術(shù)語(yǔ):其任意多次執(zhí)行所產(chǎn)生的影響均與第一次執(zhí)行的影響相同。大白話:多次調(diào)用的情況下,接口最終得到的結(jié)果是一致的。yDI28資訊網(wǎng)——每日最新資訊28at.com

3.那么為什么需要冪等呢?

  • 用戶進(jìn)行提交動(dòng)作的時(shí)候,由于網(wǎng)絡(luò)波動(dòng)等原因?qū)е潞蠖送巾憫?yīng)不及時(shí),這樣用戶就會(huì)一直點(diǎn)點(diǎn)點(diǎn),這樣機(jī)會(huì)發(fā)生重復(fù)提交的情況。
  • 分布式系統(tǒng)之間調(diào)用的情況下,例如RPC調(diào)用,為了防止網(wǎng)絡(luò)波動(dòng)超時(shí)等造成的請(qǐng)求失敗,都會(huì)添加重試機(jī)制,導(dǎo)致一個(gè)請(qǐng)求提交多次。
  • 分布式系統(tǒng)經(jīng)常會(huì)用到消息中間件,當(dāng)由于網(wǎng)絡(luò)原因,mq沒(méi)有收到ack的情況下,就會(huì)導(dǎo)致消息的重復(fù)投遞,從而就會(huì)導(dǎo)致重復(fù)提交行為。

還有就是惡意攻擊了,有些業(yè)務(wù)接口做的比較粗糙,黑客找到漏洞之后會(huì)發(fā)起重復(fù)提交,這樣就會(huì)導(dǎo)致業(yè)務(wù)出現(xiàn)問(wèn)題。打個(gè)比方,老貓?jiān)?jīng)干過(guò),鄰居小孩報(bào)名了一個(gè)畫畫比賽,估計(jì)是機(jī)構(gòu)培訓(xùn)發(fā)起的,功能做的也差,需要靠投票贏得某些禮品,然后老貓抓到接口信息之后就模擬投票進(jìn)行重復(fù)刷了投票。yDI28資訊網(wǎng)——每日最新資訊28at.com

4.那么哪些接口需要做冪等呢?

首先我們說(shuō)是不是所有的接口都需要冪等?是不是加了冪等就好呢?顯然不是。因?yàn)榻涌趦绲鹊膶?shí)現(xiàn)某種意義上是要消耗系統(tǒng)性能的,我們沒(méi)有必要針對(duì)所有業(yè)務(wù)接口都加上冪等。yDI28資訊網(wǎng)——每日最新資訊28at.com

這個(gè)其實(shí)并不能做一個(gè)完全的定義說(shuō)哪個(gè)就不用冪等,因?yàn)楹芏鄷r(shí)候其實(shí)還是得結(jié)合業(yè)務(wù)邏輯一起看。但是其中也是有規(guī)律可循的。yDI28資訊網(wǎng)——每日最新資訊28at.com

既然我們說(shuō)冪等就是多次調(diào)用,接口最終得到結(jié)果一致,那么很顯然,查詢接口肯定是不要加冪等的,另外一些簡(jiǎn)單刪除數(shù)據(jù)的接口,無(wú)論是邏輯刪除還是物理刪除,看場(chǎng)景的情況下其實(shí)也不用加冪等。yDI28資訊網(wǎng)——每日最新資訊28at.com

但是大部分涉及到多表更新行為的接口,咱們最好還是得加上冪等。yDI28資訊網(wǎng)——每日最新資訊28at.com

接口冪等實(shí)戰(zhàn)方案

1.前端防抖處理

前端防抖主要可以有兩種方案,一種是技術(shù)層面的,一種是產(chǎn)品層面的:yDI28資訊網(wǎng)——每日最新資訊28at.com

  • 技術(shù)層面:例如提交控制在100ms內(nèi),同一個(gè)用戶最多只能做一次訂單提交的操作。
  • 產(chǎn)品層面:當(dāng)然用戶點(diǎn)擊提交之后,按鈕直接置灰。

2.基于數(shù)據(jù)庫(kù)唯一索引

利用數(shù)據(jù)庫(kù)唯一索引。我們具體來(lái)看一下流程,咱們就用小貓遇到的例子。如下:yDI28資訊網(wǎng)——每日最新資訊28at.com

yDI28資訊網(wǎng)——每日最新資訊28at.com

過(guò)程描述:yDI28資訊網(wǎng)——每日最新資訊28at.com

  • 建立一張去重表,其中某個(gè)字段需要建立唯一索引,例如小貓這個(gè)場(chǎng)景中,咱們就可以將訂單提交流水單號(hào)作為唯一索引存儲(chǔ)到我們的數(shù)據(jù)庫(kù)中,就模型上而言,可以將其定義為支付請(qǐng)求流水表。
  • 客戶端攜帶相關(guān)流水信息到后端,如果發(fā)現(xiàn)編號(hào)重復(fù),那么此時(shí)就會(huì)插入失敗,報(bào)主鍵沖突的錯(cuò)誤,此時(shí)我們針對(duì)該錯(cuò)誤做一下業(yè)務(wù)報(bào)錯(cuò)的二次封裝給到客戶另一個(gè)友好的提示即可。

3.數(shù)據(jù)庫(kù)樂(lè)觀鎖實(shí)現(xiàn)

什么是樂(lè)觀鎖,它假設(shè)多用戶并發(fā)的事務(wù)在處理時(shí)不會(huì)彼此互相影響,各事務(wù)能夠在不產(chǎn)生鎖的情況下處理各自影響的那部分?jǐn)?shù)據(jù)。說(shuō)得直白一點(diǎn)樂(lè)觀鎖就是一個(gè)馬大哈??偸羌僭O(shè)最好的情況,每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人不會(huì)修改,所以不會(huì)上鎖,只在更新的時(shí)候會(huì)判斷一下在此期間別人有沒(méi)有去更新這個(gè)數(shù)據(jù)。yDI28資訊網(wǎng)——每日最新資訊28at.com

例如提交訂單的進(jìn)行支付扣款的時(shí)候,本來(lái)可能更新賬戶金額扣款的動(dòng)作是這樣的:yDI28資訊網(wǎng)——每日最新資訊28at.com

update Account set balance = balance-#{payAmount} where accountCode = #{accountCode}

加上版本號(hào)之后,咱們的代碼就是這樣的:yDI28資訊網(wǎng)——每日最新資訊28at.com

update Account set balance = balance-#{payAmount},version=version +1 where accountCode = #{accountCode} and version = #{currVersion}

這種情況下其實(shí)就要求客戶端每次在請(qǐng)求支付下單的時(shí)候都需要上層客戶端指定好當(dāng)前的版本信息。不過(guò)這種冪等的處理方式,老貓用的比較少。yDI28資訊網(wǎng)——每日最新資訊28at.com

4.數(shù)據(jù)庫(kù)悲觀鎖實(shí)現(xiàn)

悲觀鎖的話具有強(qiáng)烈的獨(dú)占和排他特性。大白話誰(shuí)都不信的主。所以我們就用select ... for update這樣的語(yǔ)法進(jìn)行行鎖,當(dāng)然老貓覺(jué)得單純的select ... for update只能解決同一時(shí)刻大并發(fā)的冪等,所以要保證單號(hào)重試這樣非并發(fā)的冪等請(qǐng)求還是得去校驗(yàn)當(dāng)前數(shù)據(jù)的狀態(tài)才行。就拿當(dāng)前的小貓遇到的場(chǎng)景來(lái)說(shuō),流程如下:yDI28資訊網(wǎng)——每日最新資訊28at.com

yDI28資訊網(wǎng)——每日最新資訊28at.com

悲觀鎖yDI28資訊網(wǎng)——每日最新資訊28at.com

begin;  # 1.開始事務(wù)select * from order where order_code='666' for update # 查詢訂單,判斷狀態(tài),鎖住這條記錄if(status !=處理中){   //非處理中狀態(tài),直接返回;   return ;}## 處理業(yè)務(wù)邏輯update order set status='完成' where order_code='666' # 更新完成update stock set num = num - 1 where spu='xxx' # 庫(kù)存更新commit; # 5.提交事務(wù)

這里老貓一再想要強(qiáng)調(diào)的是在校驗(yàn)的時(shí)候還是得帶上本身的業(yè)務(wù)狀態(tài)去做校驗(yàn),select ... for update并非萬(wàn)能冪等。yDI28資訊網(wǎng)——每日最新資訊28at.com

5.后端生成token

這個(gè)方案的本質(zhì)其實(shí)是引入了令牌桶的機(jī)制,當(dāng)提交訂單的時(shí)候,前端優(yōu)先會(huì)調(diào)用后端接口獲取一個(gè)token,token是由后端發(fā)放的。當(dāng)然token的生成方式有很多種,例如定時(shí)刷新令牌桶,或者定時(shí)生成令牌并放到令牌池中,當(dāng)然目的只有一個(gè)就是保住token的唯一性即可。yDI28資訊網(wǎng)——每日最新資訊28at.com

生成token之后將token放到redis中,當(dāng)然需要給token設(shè)置一個(gè)失效時(shí)間,超時(shí)的token也會(huì)被刪除。yDI28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)后端接收到訂單提交的請(qǐng)求的時(shí)候,會(huì)先判斷token在緩存中是否存在,第一次請(qǐng)求的時(shí)候,token一定存在,也會(huì)正常返回結(jié)果,但是第二次攜帶同一個(gè)token的時(shí)候被拒絕了。yDI28資訊網(wǎng)——每日最新資訊28at.com

流程如下:yDI28資訊網(wǎng)——每日最新資訊28at.com

yDI28資訊網(wǎng)——每日最新資訊28at.com

token機(jī)制yDI28資訊網(wǎng)——每日最新資訊28at.com

有個(gè)注意點(diǎn)大家可以思考一下:如果用戶用程序惡意刷單,同一個(gè)token發(fā)起了多次請(qǐng)求怎么辦?想要實(shí)現(xiàn)這個(gè)功能,就需要借助分布式鎖以及Lua腳本了,分布式鎖可以保證同一個(gè)token不能有多個(gè)請(qǐng)求同時(shí)過(guò)來(lái)訪問(wèn),lua腳本保證從redis中獲取令牌->比對(duì)令牌->生成單號(hào)->刪除令牌這一系列行為的原子性。yDI28資訊網(wǎng)——每日最新資訊28at.com

6.分布式鎖+狀態(tài)機(jī)(訂單狀態(tài))

現(xiàn)在很多的業(yè)務(wù)服務(wù)都是分布式系統(tǒng),所以就拿分布式鎖來(lái)說(shuō),關(guān)于分布式鎖,老貓?jiān)诖瞬蛔鲑樖觯袄县垖戇^(guò)redis的分布式鎖和實(shí)現(xiàn),還有zk鎖和實(shí)現(xiàn),具體可見鏈接:yDI28資訊網(wǎng)——每日最新資訊28at.com

  • 鎖的演化
  • 手撕redis分布式鎖
  • 手?jǐn)]ZK鎖

當(dāng)然和上述的數(shù)據(jù)庫(kù)悲觀鎖類似,咱們的分布式鎖也只能保證同一個(gè)訂單在同一時(shí)間的處理。其次也是要去校訂單的狀態(tài),防止其重復(fù)支付的,也就是說(shuō),只要支付的訂單進(jìn)入后端,都要將原先的訂單修改為支付中,防止后續(xù)支付中斷之后的重復(fù)支付。yDI28資訊網(wǎng)——每日最新資訊28at.com

在上述小貓的流程中還沒(méi)有涉及到現(xiàn)金補(bǔ)充,如果涉及到現(xiàn)金補(bǔ)充的話,例如對(duì)接了微信或者支付寶的情況,還需要根據(jù)最終的支付回調(diào)結(jié)果來(lái)最終將訂單狀態(tài)進(jìn)行流轉(zhuǎn)成支付完成或者是支付失敗。yDI28資訊網(wǎng)——每日最新資訊28at.com

總結(jié)

在我們?nèi)粘5拈_發(fā)中,一些重要的接口還是需要大家謹(jǐn)慎對(duì)待,即使是前任開發(fā)留下的接口,沒(méi)有任何改動(dòng),當(dāng)有人咨詢的時(shí)候,其實(shí)就要好好去了解一下里面的實(shí)現(xiàn),看看方案有沒(méi)有問(wèn)題,看看技術(shù)實(shí)現(xiàn)有沒(méi)有問(wèn)題,這應(yīng)該也是每一個(gè)程序員的基本素養(yǎng)。yDI28資訊網(wǎng)——每日最新資訊28at.com

另外的,在一些重要的接口上,尤其是資金相關(guān)的接口上,冪等真的是相當(dāng)?shù)闹匾P』锇閭儯銈冇X(jué)得呢?yDI28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-62793-0.html前任開發(fā)在代碼里下毒,支付下單居然沒(méi)加冪等

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: C++方差的運(yùn)算:方差求解以及方差的增量計(jì)算

下一篇: 目前為止,這些項(xiàng)目已經(jīng)被 Rust 重寫了

標(biāo)簽:
  • 熱門焦點(diǎn)
  • 小米平板5 Pro 12.4簡(jiǎn)評(píng):多專多能 兼顧影音娛樂(lè)的大屏利器

    疫情帶來(lái)了網(wǎng)課,網(wǎng)課盤活了安卓平板,安卓平板市場(chǎng)雖然中途停滯了幾年,但好的一點(diǎn)就是停滯的這幾年行業(yè)又有了新的發(fā)展方向,例如超窄邊框、高刷新率、多攝鏡頭組合等,這就讓安卓
  • 7月安卓手機(jī)性價(jià)比榜:努比亞+紅魔兩款新機(jī)入榜

    7月登場(chǎng)的新機(jī)有努比亞Z50S Pro和紅魔8S Pro,除了三星之外目前唯二的兩款搭載超頻版驍龍8Gen2處理器的產(chǎn)品,而且努比亞和紅魔也一貫有著不錯(cuò)的性價(jià)比,所以在本次的性價(jià)比榜單
  • 印度登月最關(guān)鍵一步!月船三號(hào)今晚進(jìn)入環(huán)月軌道

    8月5日消息,據(jù)印度官方消息,月船三號(hào)將于北京時(shí)間今晚21時(shí)30分左右開始近月制動(dòng)進(jìn)入環(huán)月軌道。這是該探測(cè)器能夠成功的最關(guān)鍵步驟之一,如果成功將開始圍
  • 如何正確使用:Has和:Nth-Last-Child

    我們可以用CSS檢查,以了解一組元素的數(shù)量是否小于或等于一個(gè)數(shù)字。例如,一個(gè)擁有三個(gè)或更多子項(xiàng)的grid。你可能會(huì)想,為什么需要這樣做呢?在某些情況下,一個(gè)組件或一個(gè)布局可能會(huì)
  • 得物效率前端微應(yīng)用推進(jìn)過(guò)程與思考

    一、背景效率工程隨著業(yè)務(wù)的發(fā)展,組織規(guī)模的擴(kuò)大,越來(lái)越多的企業(yè)開始意識(shí)到協(xié)作效率對(duì)于企業(yè)團(tuán)隊(duì)的重要性,甚至是決定其在某個(gè)行業(yè)競(jìng)爭(zhēng)中突圍的關(guān)鍵,是企業(yè)長(zhǎng)久生存的根本。得物
  • 微信語(yǔ)音大揭秘:為什么禁止轉(zhuǎn)發(fā)?

    大家好,我是你們的小米。今天,我要和大家聊一個(gè)有趣的話題:為什么微信語(yǔ)音不可以轉(zhuǎn)發(fā)?這是一個(gè)我們經(jīng)常在日常使用中遇到的問(wèn)題,也是一個(gè)讓很多人好奇的問(wèn)題。讓我們一起來(lái)揭開這
  • 三分鐘白話RocketMQ系列—— 如何發(fā)送消息

    我們知道RocketMQ主要分為消息 生產(chǎn)、存儲(chǔ)(消息堆積)、消費(fèi) 三大塊領(lǐng)域。那接下來(lái),我們白話一下,RocketMQ是如何發(fā)送消息的,揭秘消息生產(chǎn)全過(guò)程。注意,如果白話中不小心提到相關(guān)代
  • 認(rèn)真聊聊東方甄選:如何告別低垂的果實(shí)

    來(lái)源:山核桃作者:財(cái)經(jīng)無(wú)忌爆火一年后,俞敏洪和他的東方甄選依舊是頗受外界關(guān)心的“網(wǎng)紅”。7月5日至9日,為期5天的東方甄選“甘肅行”首次在自有App內(nèi)直播,
  • 三翼鳥智能家居亮相電博會(huì),讓用戶體驗(yàn)更真實(shí)

    2021電博會(huì)在青島國(guó)際會(huì)展中心開幕中,三翼鳥直接把“家”搬到了現(xiàn)場(chǎng),成為了展會(huì)的一大看點(diǎn)。這也是三翼鳥繼9月9日發(fā)布了行業(yè)首個(gè)一站式定制智慧家平臺(tái)后的
Top 主站蜘蛛池模板: 芦山县| 上高县| 读书| 惠来县| 桦川县| 永修县| 密山市| 白玉县| 那曲县| 耿马| 阿巴嘎旗| 蒲城县| 宁化县| 九龙城区| 密云县| 牙克石市| 尼木县| 天峨县| 南乐县| 芒康县| 大新县| 福安市| 黄陵县| 浮山县| 旅游| 三明市| 绥中县| 虞城县| 赣州市| 荣昌县| 奉节县| 通渭县| 内丘县| 门头沟区| 琼海市| 平乐县| 洞头县| 四会市| 保亭| 楚雄市| 乐至县|