摘要:對(duì)單一余額的高并發(fā)操作自然不是正常人發(fā)起的,系統(tǒng)正在承受攻擊,或者自以為是的使用了。類似于當(dāng)然,你也可以通過加入版本號(hào)概念,而不是余額字段來控制這個(gè)過程,但都類似。變種版本號(hào)通過在表中加一個(gè)額外的字段,來控制并發(fā)。
真的很危險(xiǎn),有人因此進(jìn)了局子;也有公司因此損失上億。
想象一下你在一個(gè)月黑風(fēng)高的夜晚,大概是10點(diǎn)多鐘的樣子,加班歸來,打算到小賣部弄盒煙抽。
夜涼風(fēng)急,你用力裹了下被風(fēng)鼓起的外套。
那里有你暗戀的收銀姑娘。
沒日沒夜的工作,只有這十幾分鐘,能讓你感到些許生活的意義。
從羞澀的錢包里翻出僅存的一張百元大鈔,結(jié)賬。然后用顫抖的雙手接過收銀員的找零。
不是因?yàn)檩p觸到了她的指尖。
也并非因她如花的笑靨。
只因?yàn)?,腦海里竟然不爭(zhēng)氣的浮現(xiàn)出這樣的過程。
balance = dao.getBalance(userid) balance = balance - cost dao.setBalance(userid,balance)
還真是狗改不了吃屎啊,果然還是一個(gè)碼畜。提醒著自己,自卑的埋下了臉,快步走開。
這是什么?這是我們送給996公司的一點(diǎn)福報(bào)。
一波麻6的操作余額修改,是交易系統(tǒng)里最常見的操作。上面的偽代碼,大意是先取出余額,然后扣掉消費(fèi),然后再回寫余額。通常情況下這不會(huì)發(fā)生問題。
除非是高并發(fā),與你是否單機(jī)無關(guān)。
對(duì)單一余額的高并發(fā)操作自然不是正常人發(fā)起的,系統(tǒng)正在承受攻擊,或者自以為是的使用了MQ。在攻擊面前,上面的操作顯得不堪一擊。
拿一個(gè)最嚴(yán)重的例子說明:同時(shí)發(fā)起了一筆消費(fèi)20元和消費(fèi)5元的請(qǐng)求。在經(jīng)過一波猛如虎的操作之后,兩個(gè)請(qǐng)求都支付成功了,但只扣除了5元。相當(dāng)于花了5塊錢,買了25的東西。
劃重點(diǎn):把以上操作擴(kuò)展到提現(xiàn)操作上,就更加的恐怖。比如你發(fā)起了一筆100元的提現(xiàn)和0.01元的提現(xiàn),結(jié)果余額被扣減0.01元的提現(xiàn)給覆蓋了。這相當(dāng)于你有了一個(gè)提款機(jī),非要薅到平臺(tái)倒閉為止。
update user set balance = balance - 20 where userid=id
這條語句就保險(xiǎn)了很多,如果考慮到余額不能為負(fù)的情況,可以把sql更加精進(jìn)一點(diǎn)。
update user set balance = balance - 20 where userid=id and balance >= 20
以上sql,就可以保證余額的安全,高并發(fā)下的攻擊就變得意義不大了。?但會(huì)有別的問題,比如重復(fù)扣款。
通過鎖解決現(xiàn)實(shí)中,這種直接通過sql扣減的應(yīng)用,規(guī)模都比較小。當(dāng)你的業(yè)務(wù)逐漸復(fù)雜,又沒有進(jìn)行很好的拆分的情況下,先讀再設(shè)值的情況還是比較普遍的。比如某些營(yíng)銷操作、打折、積分兌換等。
這種情況,可以引入分布式鎖。簡(jiǎn)單點(diǎn)的,只需要使用redis的setnx或者zk來控制就可以;復(fù)雜點(diǎn)的方案,可以使用二階段提交之類的。
分布式事務(wù)的業(yè)務(wù)粒度,要足夠粗,才能保護(hù)這些余額操作;加鎖的粒度,要足夠細(xì),才能保證系統(tǒng)的效率。
begin transition(userid) balance = dao.getBalance(userid) balance = balance - cost dao.setBalance(userid,balance) end類CAS方式解決
java的朋友可以回想下concurrent包的解決方式。那就是引入了CAS,全稱Compare And Set。
擴(kuò)展到分布式環(huán)境下,同樣可以采用這一策略。即先比較再設(shè)值。如果初始值已經(jīng)變化了,那么不允許set設(shè)值。
cas一般通過循環(huán)重試的方法進(jìn)行狀態(tài)更新,但余額操作一般都是比較單一的,你也可以直接終止操作,并預(yù)警風(fēng)險(xiǎn)。
sql類似于:
update user set balance = balance - 20 where userid=id and balance >= 20 and balance = $old_balance
當(dāng)然,你也可以通過加入版本號(hào)概念,而不是余額字段來控制這個(gè)過程,但都類似。
變種:版本號(hào)通過在表中加一個(gè)額外的字段version,來控制并發(fā)。這種方式不去關(guān)注余額,可擴(kuò)展性更強(qiáng)。
version的默認(rèn)值一般是1,即記錄創(chuàng)建時(shí)的默認(rèn)值。
操作的偽代碼如下:
version,balance = dao.getBalance(userid) balance = balance - cost dao.exec(" update user set balance = balance - 20 version = version + 1 where userid=id and balance >= 20 and version = $old_version ")
上面的并發(fā)攻擊,將會(huì)只有一個(gè)操作能夠成功,我們的余額安全了。
End趕緊看一下你的余額操作,是否也暴露在風(fēng)險(xiǎn)之下。你可以選擇接受福報(bào)繼續(xù)當(dāng)兄弟,當(dāng)然也可以將福報(bào)還給資本家。
一念成佛,一念成魔。你才是自己的主人。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/74112.html
摘要:在前幾天的阿里內(nèi)部交流活動(dòng)上,我們的馬總也與其員工討論了話題,包括自己創(chuàng)辦阿里的成長(zhǎng)過程。馬總的一番話點(diǎn)醒了一批互聯(lián)網(wǎng)行業(yè)的我們。馬總說馬云提到,能做是一種巨大的福氣,很多公司很多人想都沒有機(jī)會(huì)。 最近的一個(gè)996話題在互聯(lián)網(wǎng)業(yè)界,可以說是非常的火熱。身為互聯(lián)網(wǎng)人,也在時(shí)時(shí)關(guān)注的,畢竟和我們的生活息息相關(guān)。在前幾天的阿里內(nèi)部交流活動(dòng)上,我們的馬總也與其員工討論了996話題,包括自己創(chuàng)辦...
摘要:更進(jìn)一步,馬云的好朋友兼董事的楊致遠(yuǎn)被資本聯(lián)合踢出董事會(huì),這也意味著馬云逐漸喪失對(duì)阿里巴巴的控制權(quán),甚至面臨出局的危險(xiǎn)。阿里的招聘阿里的招聘在初中級(jí)崗位中的要求如下阿里軟件測(cè)試工程師招聘需求需要我們注意的是崗位需求中對(duì)技術(shù)的要求會(huì)更加嚴(yán)格。 ...
摘要:因?yàn)榫W(wǎng)站建設(shè)一般項(xiàng)目比較小,我一個(gè)人是可以完成前后端開發(fā)的,如果做成成品當(dāng)然得加上小蘇設(shè)計(jì)師。關(guān)鍵詞選擇因?yàn)槊嫦虻氖菃蝹€(gè)城市業(yè)務(wù),在城市選擇上猶豫了不少時(shí)間,首先得是一個(gè)大城市,客戶量足,當(dāng)時(shí)我在北京,小蘇是在一個(gè)省會(huì)城市。 我技術(shù)之外的資本是零,如果你也是這樣,那這篇文章適合你! 這是我的故事之一,希望對(duì)你有啟發(fā)。如果你每天下班后就是躺在床上刷刷斗音,看看微博。但是又總想擺脫黑暗迷亂...
摘要:因?yàn)榫W(wǎng)站建設(shè)一般項(xiàng)目比較小,我一個(gè)人是可以完成前后端開發(fā)的,如果做成成品當(dāng)然得加上小蘇設(shè)計(jì)師。關(guān)鍵詞選擇因?yàn)槊嫦虻氖菃蝹€(gè)城市業(yè)務(wù),在城市選擇上猶豫了不少時(shí)間,首先得是一個(gè)大城市,客戶量足,當(dāng)時(shí)我在北京,小蘇是在一個(gè)省會(huì)城市。 我技術(shù)之外的資本是零,如果你也是這樣,那這篇文章適合你! 這是我的故事之一,希望對(duì)你有啟發(fā)。如果你每天下班后就是躺在床上刷刷斗音,看看微博。但是又總想擺脫黑暗迷亂...
摘要:因?yàn)榫W(wǎng)站建設(shè)一般項(xiàng)目比較小,我一個(gè)人是可以完成前后端開發(fā)的,如果做成成品當(dāng)然得加上小蘇設(shè)計(jì)師。關(guān)鍵詞選擇因?yàn)槊嫦虻氖菃蝹€(gè)城市業(yè)務(wù),在城市選擇上猶豫了不少時(shí)間,首先得是一個(gè)大城市,客戶量足,當(dāng)時(shí)我在北京,小蘇是在一個(gè)省會(huì)城市。 我技術(shù)之外的資本是零,如果你也是這樣,那這篇文章適合你! 這是我的故事之一,希望對(duì)你有啟發(fā)。如果你每天下班后就是躺在床上刷刷斗音,看看微博。但是又總想擺脫黑暗迷亂...
閱讀 1089·2021-11-24 09:39
閱讀 1320·2021-11-18 13:18
閱讀 2468·2021-11-15 11:38
閱讀 1841·2021-09-26 09:47
閱讀 1641·2021-09-22 15:09
閱讀 1635·2021-09-03 10:29
閱讀 1522·2019-08-29 17:28
閱讀 2962·2019-08-29 16:30