摘要:每年支付寶在雙和雙的活動(dòng)中,都展示了絕佳的技術(shù)能力。對(duì)于異步并發(fā)重復(fù)消息的處理亦是如此,加深對(duì)狀態(tài)機(jī)的判斷后還可以處理消息亂序問題。
每年支付寶在雙11和雙12的活動(dòng)中,都展示了絕佳的技術(shù)能力。這個(gè)能力不但體現(xiàn)在處理高TPS量的訪問,更體現(xiàn)在幾乎不會(huì)出錯(cuò),不會(huì)出現(xiàn)重復(fù)支付的情況,那這個(gè)是怎么做到的呢?
誠然,為了實(shí)現(xiàn)在高并發(fā)下仍不會(huì)出錯(cuò)的技術(shù)目標(biāo),支付寶下了很多功夫,比如冪等性的處理,分布式事務(wù)的使用等等,但是個(gè)人覺得其中最關(guān)鍵的一點(diǎn)就是“一鎖二判三更新”這句看似毫不起眼的口訣。
何為“一鎖二判三更新”? 簡(jiǎn)單來說就是當(dāng)任何一個(gè)并發(fā)請(qǐng)求過來的時(shí)候
我們先鎖定關(guān)聯(lián)單據(jù)
然后判斷關(guān)聯(lián)單據(jù)狀態(tài),是否之前已經(jīng)更新過對(duì)應(yīng)狀態(tài)了
如果基于第2步判斷,之前并沒有請(qǐng)求更新過對(duì)應(yīng)狀態(tài),則本次請(qǐng)求可以更新并完成相關(guān)業(yè)務(wù)邏輯。如果之前已經(jīng)有更新過狀態(tài)了,則本次不能更新,也不能完成業(yè)務(wù)邏輯。
示意圖
話不多說,我們直接上代碼:
//第1步鎖當(dāng)前支付單 PaymentInfo resultPaymentInfo = commonPayCoreService .queryPaymentForUpdate(createPaymentInfo.getId()); if (resultPaymentInfo.isFinalStatus()) { //第2步,判斷當(dāng)前支付單狀態(tài),如果是終態(tài),則直接返回 //不做任何更新 return resultPaymentInfo; } //第3步更新當(dāng)前支付單狀態(tài)到終態(tài),并完成相關(guān)業(yè)務(wù)邏輯(支付成功) payCoreService.updateRequestResult(payChannelResult);
基于以上方案可以100%確保在并發(fā)情況下不會(huì)出現(xiàn)重復(fù)更新問題,按理論來說,就是每次狀態(tài)機(jī)變更前,都要在并發(fā)安全情況下判斷狀態(tài)是否已經(jīng)發(fā)生過變更了。
如果第1步或第2步缺失了,會(huì)發(fā)生什么問題,我們來看一下:
第1步缺失
第2步缺失
只要把這3步作為我們的代碼規(guī)范,則可以避免大部分的并發(fā)重復(fù)操作問題。對(duì)于異步并發(fā)重復(fù)消息的處理亦是如此,加深對(duì)狀態(tài)機(jī)的判斷后還可以處理消息亂序問題。
對(duì)于鎖的使用可根據(jù)實(shí)際情況選擇悲觀鎖和樂觀鎖。
關(guān)于悲觀鎖(數(shù)據(jù)庫行鎖),樂觀鎖(數(shù)據(jù)庫版本鎖或分布式鎖)的實(shí)現(xiàn)方式和坑我們以后再詳細(xì)說。
可能有人會(huì)問不管是悲觀鎖還是樂觀鎖對(duì)系統(tǒng)的并發(fā)量都是有影響的,這個(gè)怎么解決?我的觀點(diǎn)是在現(xiàn)代分布式系統(tǒng)中,如果追求高可用和穩(wěn)定則必須在方案上優(yōu)先滿足,對(duì)于性能可以通過優(yōu)化代碼邏輯,優(yōu)化技術(shù)架構(gòu),擴(kuò)展數(shù)據(jù)庫資源等方式來解決。
在之前螞蟻金服的壓測(cè)中,我負(fù)責(zé)的結(jié)算系統(tǒng)內(nèi)部有10次左右SQL調(diào)用以及一次遠(yuǎn)程調(diào)用(約花費(fèi)100ms),總流程花費(fèi)180ms左右。在一臺(tái)4核8G的機(jī)器上壓測(cè),java服務(wù)并發(fā)可以達(dá)到150TPS,結(jié)果還是令人滿意的,通過水平服務(wù)器擴(kuò)展完全沒有問題。
在整個(gè)支付寶技術(shù)架構(gòu)中,只有一個(gè)場(chǎng)景是沒有用鎖和判斷直接更新的,就是2016年的春節(jié)五福紅包,高達(dá)上百萬的TPS訪問,為了保證用戶的順暢體驗(yàn),犧牲了狀態(tài)判斷的安全性,在事后再做一次對(duì)賬(雖然就算出錯(cuò)也于事無補(bǔ)了 :))
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/70427.html
摘要:每年支付寶在雙和雙的活動(dòng)中,都展示了絕佳的技術(shù)能力。對(duì)于異步并發(fā)重復(fù)消息的處理亦是如此,加深對(duì)狀態(tài)機(jī)的判斷后還可以處理消息亂序問題。 每年支付寶在雙11和雙12的活動(dòng)中,都展示了絕佳的技術(shù)能力。這個(gè)能力不但體現(xiàn)在處理高TPS量的訪問,更體現(xiàn)在幾乎不會(huì)出錯(cuò),不會(huì)出現(xiàn)重復(fù)支付的情況,那這個(gè)是怎么做到的呢? 誠然,為了實(shí)現(xiàn)在高并發(fā)下仍不會(huì)出錯(cuò)的技術(shù)目標(biāo),支付寶下了很多功夫,比如冪等性的處理,...
摘要:解決冪等問題的三部曲,也是作者的思考框架。這是解決冪等問題的第二部曲列出并減少副作用的分析維度。所以在并發(fā)執(zhí)行的維度,將并發(fā)重復(fù)執(zhí)行變成串行重復(fù)執(zhí)行是最好的冪等解決方案。 綱要 文章目的:本文旨在提煉一套分布式冪等問題的思考框架,而非解決某個(gè)具體的分布式冪等問題。在這個(gè)框架體系內(nèi),會(huì)有一些方案舉例說明。文章目標(biāo):希望讀者能通過這套思考框架設(shè)計(jì)出符合自己業(yè)務(wù)的完備的冪等解決方案。文章內(nèi)容...
要了解 VPS 存在的原因,我們可能應(yīng)該退后一步,先看看服務(wù)器。服務(wù)器是通過網(wǎng)絡(luò)向其他計(jì)算機(jī)提供文件或數(shù)據(jù)的計(jì)算機(jī)。服務(wù)器可以通過鼠標(biāo)或鍵盤直接訪問,也可以是所謂的無頭服務(wù)器,只能遠(yuǎn)程訪問。整個(gè)互聯(lián)網(wǎng)的核心不過是大量互連服務(wù)器的集合。要在線執(zhí)行任何操作,例如啟動(dòng) How-To Geek 之類的網(wǎng)站或運(yùn)行天氣應(yīng)用程序等服務(wù),您需要在服務(wù)器上運(yùn)行程序或托管文件。沒有服務(wù)器,沒有站點(diǎn)。但問題是,服務(wù)器是...
閱讀 740·2021-11-17 09:33
閱讀 3772·2021-09-01 10:46
閱讀 1762·2019-08-30 11:02
閱讀 3290·2019-08-29 15:05
閱讀 1407·2019-08-26 11:39
閱讀 2283·2019-08-23 17:04
閱讀 1982·2019-08-23 15:43
閱讀 1379·2019-08-23 14:12