免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項超值服

開通VIP
再有人問你分布式鎖,就把這個丟給他!

作者介紹

現(xiàn)在面試都會聊聊分布式系統(tǒng),通常面試官都會從服務(wù)框架(Spring Cloud、Dubbo),一路聊到分布式事務(wù)、分布式鎖、ZooKeeper等知識。今天就來聊聊分布式鎖這塊的知識,先具體的來看看Redis分布式鎖的實現(xiàn)原理。

如果在公司里落地生產(chǎn)環(huán)境用分布式鎖的時候,一定是會用開源類庫的,比如Redis分布式鎖,一般就是用Redisson框架就好了,非常的簡便易用。感興趣可以去Redisson官網(wǎng)看看如何在項目中引入Redisson的依賴,然后基于Redis實現(xiàn)分布式鎖的加鎖與釋放鎖。

一段簡單的使用代碼片段,先直觀的感受一下:

是不是感覺簡單的不行!此外,還支持Redis單實例、Redis哨兵、Redis Cluster、redis master-slave等各種部署架構(gòu),都可以完美實現(xiàn)。

一、Redisson實現(xiàn)Redis分布式鎖的底層原理

現(xiàn)在通過一張手繪圖,說說Redisson這個開源框架對Redis分布式鎖的實現(xiàn)原理。

1、加鎖機(jī)制

看上面那張圖,現(xiàn)在某個客戶端要加鎖。如果該客戶端面對的是一個Redis Cluster集群,他首先會根據(jù)Hash節(jié)點選擇一臺機(jī)器。

注:僅僅只是選擇一臺機(jī)器!然后發(fā)送一段Lua腳本到Redis上,那段Lua腳本如下所示:

為啥要用Lua腳本呢?因為一大坨復(fù)雜的業(yè)務(wù)邏輯,可以通過封裝在Lua腳本中發(fā)送給Redis,保證這段復(fù)雜業(yè)務(wù)邏輯執(zhí)行的原子性。

那么,這段Lua腳本是什么意思呢?這里KEYS[1]代表的是你加鎖的那個Key,比如說:RLock lock = redisson.getLock('myLock');這里你自己設(shè)置了加鎖的那個鎖Key就是“myLock”。

  • ARGV[1]代表的就是鎖Key的默認(rèn)生存時間,默認(rèn)30秒。

  • ARGV[2]代表的是加鎖的客戶端的ID,類似于下面這樣的:8743c9c0-0795-4907-87fd-6c719a6b4586:1。

第一段if判斷語句,就是用“exists myLock”命令判斷一下,如果你要加鎖的那個鎖Key不存在的話,你就進(jìn)行加鎖。如何加鎖呢?很簡單,用下面的命令:hset myLock。

8743c9c0-0795-4907-87fd-6c719a6b4586:11,通過這個命令設(shè)置一個Hash數(shù)據(jù)結(jié)構(gòu),這行命令執(zhí)行后,會出現(xiàn)一個類似下面的數(shù)據(jù)結(jié)構(gòu):

上述內(nèi)容就代表“8743c9c0-0795-4907-87fd-6c719a6b4586:1”這個客戶端,已經(jīng)對“myLock”這個鎖Key完成了加鎖。

接著會執(zhí)行“pexpiremyLock 30000”命令,設(shè)置myLock這個鎖Key的生存時間是30秒,加鎖完成。

2、鎖互斥機(jī)制

這個時候,如果客戶端2來嘗試加鎖,執(zhí)行了同樣的一段Lua腳本,會怎樣?

第一個if判斷會執(zhí)行“exists myLock”,發(fā)現(xiàn)myLock這個鎖Key已經(jīng)存在了。

第二個if判斷,判斷myLock鎖Key的Hash數(shù)據(jù)結(jié)構(gòu)中,是否包含客戶端2的ID,但是明顯不是的,因為那里包含的是客戶端1的ID。

所以,客戶端2會獲取到pttl myLock返回的一個數(shù)字,這個數(shù)字代表了myLock這個鎖Key的剩余生存時間。比如還剩15000毫秒的生存時間。此時客戶端2會進(jìn)入一個while循環(huán),不停的嘗試加鎖。

3、watch dog自動延期機(jī)制

客戶端1加鎖的鎖Key默認(rèn)生存時間才30秒,如果超過了30秒,客戶端1還想一直持有這把鎖,怎么辦呢?

只要客戶端1加鎖成功,就會啟動一個watchdog看門狗,這個后臺線程,會每隔10秒檢查一下,如果客戶端1還持有鎖Key,就會不斷的延長鎖Key的生存時間。

4、可重入加鎖機(jī)制

那如果客戶端1都已經(jīng)持有了這把鎖了,結(jié)果可重入的加鎖會怎么樣呢?如下代碼:

分析一下上面那段Lua腳本。第一個if判斷肯定不成立,“exists myLock”會顯示鎖Key已經(jīng)存在了。

第二個if判斷會成立,因為myLock的Hash數(shù)據(jù)結(jié)構(gòu)中包含的那個ID,就是客戶端1的那個ID,也就是“8743c9c0-0795-4907-87fd-6c719a6b4586:1”。

此時就會執(zhí)行可重入加鎖的邏輯,incrby myLock 8743c9c0-0795-4907-87fd-6c71a6b4586:11,通過這個命令,對客戶端1的加鎖次數(shù),累加1。

此時myLock數(shù)據(jù)結(jié)構(gòu)變?yōu)橄旅孢@樣:

myLock的Hash數(shù)據(jù)結(jié)構(gòu)中的那個客戶端ID,就對應(yīng)著加鎖的次數(shù)。

5、釋放鎖機(jī)制

如果執(zhí)行l(wèi)ock.unlock,就可以釋放分布式鎖,此時的業(yè)務(wù)邏輯也是非常簡單的。就是每次都對myLock數(shù)據(jù)結(jié)構(gòu)中的那個加鎖次數(shù)減1。

如果發(fā)現(xiàn)加鎖次數(shù)是0了,說明這個客戶端已經(jīng)不再持有鎖了,此時就會用:“del myLock”命令,從Redis里刪除這個Key。

而另外的客戶端2就可以嘗試完成加鎖了。這就是所謂的分布式鎖的開源Redisson框架的實現(xiàn)機(jī)制。

一般我們在生產(chǎn)系統(tǒng)中,可以用Redisson框架提供的這個類庫來基于Redis進(jìn)行分布式鎖的加鎖與釋放鎖。

6、上述Redis分布式鎖的缺點

上面那種方案最大的問題,就是如果你對某個Redis Master實例,寫入了myLock這種鎖Key的Value,此時會異步復(fù)制給對應(yīng)的Master Slave實例。

但是這個過程中一旦發(fā)生Redis Master宕機(jī),主備切換,Redis Slave變?yōu)榱薘edis Master。

會導(dǎo)致客戶端2嘗試加鎖時,在新的Redis Master上完成加鎖,客戶端1也以為自己成功加鎖。

此時就會導(dǎo)致多個客戶端對一個分布式鎖完成了加鎖。這時系統(tǒng)在業(yè)務(wù)語義上一定會出現(xiàn)問題,導(dǎo)致各種臟數(shù)據(jù)的產(chǎn)生。

所以這個就是Redis Cluster,或者是redis master-slave架構(gòu)的主從異步復(fù)制導(dǎo)致的Redis分布式鎖的最大缺陷:在Redis Master實例宕機(jī)的時候,可能導(dǎo)致多個客戶端同時完成加鎖。

二、七張圖徹底講清楚ZooKeeper分布式鎖的實現(xiàn)原理

下面再聊一下ZooKeeper實現(xiàn)分布式鎖的原理。同理,我是直接基于比較常用的Curator這個開源框架,聊一下這個框架對ZooKeeper(以下簡稱ZK)分布式鎖的實現(xiàn)。

一般除了大公司是自行封裝分布式鎖框架之外,建議大家用這些開源框架封裝好的分布式鎖實現(xiàn),這是一個比較快捷省事的方式。

ZooKeeper分布式鎖機(jī)制

看看多客戶端獲取及釋放ZK分布式鎖的整個流程及背后的原理。首先看看下圖,如果現(xiàn)在有兩個客戶端一起要爭搶ZK上的一把分布式鎖,會是個什么場景?

如果大家對ZK還不太了解的話,建議先自行百度一下,簡單了解點基本概念,比如ZK有哪些節(jié)點類型等等。

參見上圖。ZK里有一把鎖,這個鎖就是ZK上的一個節(jié)點。兩個客戶端都要來獲取這個鎖,具體是怎么來獲取呢?

假設(shè)客戶端A搶先一步,對ZK發(fā)起了加分布式鎖的請求,這個加鎖請求是用到了ZK中的一個特殊的概念,叫做“臨時順序節(jié)點”。簡單來說,就是直接在'my_lock'這個鎖節(jié)點下,創(chuàng)建一個順序節(jié)點,這個順序節(jié)點有ZK內(nèi)部自行維護(hù)的一個節(jié)點序號。

  • 比如第一個客戶端來搞一個順序節(jié)點,ZK內(nèi)部會給起個名字叫做:xxx-000001。

  • 然后第二個客戶端來搞一個順序節(jié)點,ZK可能會起個名字叫做:xxx-000002。

  • 注意,最后一個數(shù)字都是依次遞增的,從1開始逐次遞增。ZK會維護(hù)這個順序。

所以這個時候,假如說客戶端A先發(fā)起請求,就會搞出來一個順序節(jié)點,大家看下圖,Curator框架大概會弄成如下的樣子:

客戶端A發(fā)起一個加鎖請求,先在要加鎖的node下搞一個臨時順序節(jié)點,這列長名字都是Curator框架自己生成出來的。

然后,那個最后一個數(shù)字是'1'。因為客戶端A是第一個發(fā)起請求的,所以給他搞出來的順序節(jié)點的序號是'1'。

接著客戶端A創(chuàng)建完一個順序節(jié)點。還沒完,他會查一下'my_lock'這個鎖節(jié)點下的所有子節(jié)點,并且這些子節(jié)點是按照序號排序的,這個時候他大概會拿到這么一個集合:

接著客戶端A會走一個關(guān)鍵性的判斷:這個集合里創(chuàng)建的順序節(jié)點,是否排在首位?

如果是的話,就可以加鎖,因為明明我就是第一個來創(chuàng)建順序節(jié)點的人,所以我就是第一個嘗試加分布式鎖的人??!

加鎖成功!看下圖,再來直觀的感受一下整個過程:

接著假如說,客戶端A都加完鎖了,客戶端B過來想要加鎖了,這個時候他會干一樣的事兒:先是在'my_lock'這個鎖節(jié)點下創(chuàng)建一個臨時順序節(jié)點,此時名字會變成類似于:

下圖:

客戶端B因為是第二個來創(chuàng)建順序節(jié)點的,所以ZK內(nèi)部會維護(hù)序號為'2'。

接著客戶端B會走加鎖判斷邏輯,查詢'my_lock'鎖節(jié)點下的所有子節(jié)點,按序號順序排列,此時他看到的類似于:

同時檢查自己創(chuàng)建的順序節(jié)點,是不是集合中的第一個?明顯不是啊,此時第一個是客戶端A創(chuàng)建的那個順序節(jié)點,序號為'01'的那個。所以加鎖失敗!

加鎖失敗了以后,客戶端B就會通過ZK的API對他的順序節(jié)點的上一個順序節(jié)點加一個監(jiān)聽器。ZK天然就可以實現(xiàn)對某個節(jié)點的監(jiān)聽。

如果大家還不知道ZK的基本用法,可以百度查閱,非常的簡單。客戶端B的順序節(jié)點是:

他的上一個順序節(jié)點,不就是下面這個嗎?

即客戶端A創(chuàng)建的那個順序節(jié)點!所以,客戶端B會對:

這個節(jié)點加一個監(jiān)聽器,監(jiān)聽這個節(jié)點是否被刪除等變化!大家看下圖:

接著,客戶端A加鎖之后,可能處理了一些代碼邏輯,然后就會釋放鎖。那么,釋放鎖是個什么過程呢?

其實就是把自己在ZK里創(chuàng)建的那個順序節(jié)點,也就是:

這個節(jié)點刪除。刪除了那個節(jié)點之后,ZK會負(fù)責(zé)通知監(jiān)聽這個節(jié)點的監(jiān)聽器,也就是客戶端B之前加的那個監(jiān)聽器,說:你監(jiān)聽的那個節(jié)點被刪除了,有人釋放了鎖。

此時客戶端B的監(jiān)聽器感知到了上一個順序節(jié)點被刪除,也就是排在他之前的某個客戶端釋放了鎖。

此時,就會通知客戶端B重新嘗試去獲取鎖,也就是獲取'my_lock'節(jié)點下的子節(jié)點集合,此時為:

集合里此時只有客戶端B創(chuàng)建的唯一的一個順序節(jié)點了!然后呢,客戶端B判斷自己居然是集合中的第一個順序節(jié)點,Bingo!可以加鎖了!直接完成加鎖,運(yùn)行后續(xù)的業(yè)務(wù)代碼即可,運(yùn)行完了之后再次釋放鎖。

其實如果有客戶端C、客戶端D等N個客戶端爭搶一個ZK分布式鎖,原理都是類似的:

  • 大家都是上來直接創(chuàng)建一個鎖節(jié)點下的一個接一個的臨時順序節(jié)點。

  • 如果自己不是第一個節(jié)點,就對自己上一個節(jié)點加監(jiān)聽器。

  • 只要上一個節(jié)點釋放鎖,自己就排到前面去了,相當(dāng)于是一個排隊機(jī)制。

  • 而且用臨時順序節(jié)點的另外一個用意就是,如果某個客戶端創(chuàng)建臨時順序節(jié)點之后,不小心自己宕機(jī)了也沒關(guān)系,ZK感知到那個客戶端宕機(jī),會自動刪除對應(yīng)的臨時順序節(jié)點,相當(dāng)于自動釋放鎖,或者是自動取消自己的排隊。

最后,咱們來看下用Curator框架進(jìn)行加鎖和釋放鎖的一個過程:

其實用開源框架就是方便。這個Curator框架的ZK分布式鎖的加鎖和釋放鎖的實現(xiàn)原理,就是上面我們說的那樣子。

但是如果你要手動實現(xiàn)一套那個代碼的話,要考慮到各種細(xì)節(jié),異常處理等等。所以大家如果考慮用ZK分布式鎖,可以參考下本文的思路。

三、每秒上千訂單場景下的分布式鎖高并發(fā)優(yōu)化實踐

接著聊一個有意思的話題:每秒上千訂單場景下,如何對分布式鎖的并發(fā)能力進(jìn)行優(yōu)化?

首先,我們一起來看看這個問題的背景。前段時間有個朋友在外面面試,然后有一天找我聊說:有一個國內(nèi)不錯的電商公司,面試官給他出了一個場景題:

假如下單時,用分布式鎖來防止庫存超賣,但是是每秒上千訂單的高并發(fā)場景,如何對分布式鎖進(jìn)行高并發(fā)優(yōu)化來應(yīng)對這個場景?

他說他當(dāng)時沒答上來,因為沒做過沒什么思路。其實我當(dāng)時聽到這個面試題心里也覺得有點意思,因為如果是我來面試候選人的話,給的范圍會更大一些。比如,讓面試的同學(xué)聊一聊電商高并發(fā)秒殺場景下的庫存超賣解決方案,各種方案的優(yōu)缺點以及實踐,進(jìn)而聊到分布式鎖這個話題。

因為庫存超賣問題是有很多種技術(shù)解決方案的,比如悲觀鎖,分布式鎖,樂觀鎖,隊列串行化,Redis原子操作,等等吧。但是既然那個面試官兄弟限定死了用分布式鎖來解決庫存超賣,我估計就是想問一個點:在高并發(fā)場景下如何優(yōu)化分布式鎖的并發(fā)性能。

面試官提問的角度還是可以接受的,因為在實際落地生產(chǎn)的時候,分布式鎖這個東西保證了數(shù)據(jù)的準(zhǔn)確性,但是他天然并發(fā)能力有點弱。

剛好我之前在自己項目的其他場景下,確實是做過高并發(fā)場景下的分布式鎖優(yōu)化方案,因此正好是借著這個朋友的面試題,把分布式鎖的高并發(fā)優(yōu)化思路,給大家來聊一聊。

1、庫存超賣現(xiàn)象是怎么產(chǎn)生的?

先來看看如果不用分布式鎖,所謂的電商庫存超賣是啥意思?大家看下圖:

這個圖其實很清晰了,假設(shè)訂單系統(tǒng)部署在兩臺機(jī)器上,不同的用戶都要同時買10臺iPhone,分別發(fā)了一個請求給訂單系統(tǒng)。

接著每個訂單系統(tǒng)實例都去數(shù)據(jù)庫里查了一下,當(dāng)前iPhone庫存是12臺,大于了要買的10臺數(shù)量。

于是每個訂單系統(tǒng)實例都發(fā)送SQL到數(shù)據(jù)庫里下單,然后扣減了10個庫存,其中一個將庫存從12臺扣減為2臺,另外一個將庫存從2臺扣減為-8臺。

現(xiàn)在庫存出現(xiàn)了負(fù)數(shù)!沒有20臺iPhone發(fā)給兩個用戶??!怎么辦?

2、用分布式鎖如何解決庫存超賣問題?

我們用分布式鎖如何解決庫存超賣問題呢?回憶一下上次我們說的那個分布式鎖的實現(xiàn)原理:

同一個鎖Key,同一時間只能有一個客戶端拿到鎖,其他客戶端會陷入無限的等待來嘗試獲取那個鎖,只有獲取到鎖的客戶端才能執(zhí)行下面的業(yè)務(wù)邏輯。

代碼如上圖,分析一下為什么這樣可以避免庫存超賣?

大家可以順著上面的那個步驟序號看一遍,馬上就明白了。

從上圖可以看到,只有一個訂單系統(tǒng)實例可以成功加分布式鎖,然后只有他一個實例可以查庫存、判斷庫存是否充足、下單扣減庫存,接著釋放鎖。釋放鎖之后,另外一個訂單系統(tǒng)實例才能加鎖,接著查庫存,一下發(fā)現(xiàn)庫存只有2臺了,庫存不足,無法購買,下單失敗。不會將庫存扣減為-8的。

3、有沒其他方案解決庫存超賣問題?

當(dāng)然有!比如悲觀鎖,分布式鎖,樂觀鎖,隊列串行化,異步隊列分散,Redis原子操作,等等,很多方案,我們對庫存超賣有自己的一整套優(yōu)化機(jī)制。但是前面說過,這篇文章就聊一個分布式鎖的并發(fā)優(yōu)化,不是聊庫存超賣的解決方案,所以庫存超賣只是一個業(yè)務(wù)場景而已。

4、分布式鎖的方案在高并發(fā)場景下

現(xiàn)在我們來看看,分布式鎖的方案在高并發(fā)場景下有什么問題?分布式鎖一旦加了之后,對同一個商品的下單請求,會導(dǎo)致所有客戶端都必須對同一個商品的庫存鎖Key進(jìn)行加鎖。

比如,對iPhone這個商品的下單,都必對“iphone_stock”這個鎖Key來加鎖。這樣會導(dǎo)致對同一個商品的下單請求,就必須串行化,一個接一個的處理。大家再回去對照上面的圖反復(fù)看一下,應(yīng)該能想明白這個問題。

假設(shè)加鎖之后,釋放鎖之前,查庫存→創(chuàng)建訂單→扣減庫存,這個過程性能很高吧,算他全過程20毫秒,這應(yīng)該不錯了。那么1秒是1000毫秒,只能容納50個對這個商品的請求依次串行完成處理。如一秒鐘50個請求,都是對iPhone下單的,那么每個請求處理20毫秒,逐個來,最后1000毫秒正好處理完50個請求。

大家看下圖,加深印象。

所以看到這里,大家起碼也明白了,簡單的使用分布式鎖來處理庫存超賣問題,存在什么缺陷。

同一商品多用戶同時下單時,會基于分布式鎖串行化處理,導(dǎo)致沒法同時處理同一個商品的大量下單的請求。這種方案應(yīng)對那種低并發(fā)、無秒殺場景的普通小電商系統(tǒng),可能還可以接受。

因為如果并發(fā)量很低,每秒就不到10個請求,沒有瞬時高并發(fā)秒殺單個商品的場景的話,其實也很少會對同一個商品在1秒內(nèi)瞬間下1000個訂單,因為小電商系統(tǒng)沒那場景。

5、如何對分布式鎖進(jìn)行高并發(fā)優(yōu)化?

那么現(xiàn)在怎么辦呢?面試官說,我現(xiàn)在就卡死,庫存超賣就是用分布式鎖來解決,而且一秒對一個iPhone下上千訂單,怎么優(yōu)化?

現(xiàn)在按照剛才的計算,你1秒鐘只能處理針對iPhone的50個訂單。其實說出來也很簡單,相信很多人看過Java里的Concurrent Hash Map的源碼和底層原理,應(yīng)該知道里面的核心思路,就是分段加鎖!

把數(shù)據(jù)分成很多個段,每個段是一個單獨(dú)的鎖,所以多個線程過來并發(fā)修改數(shù)據(jù)的時候,可以并發(fā)的修改不同段的數(shù)據(jù)。不至于說,同一時間只能有一個線程獨(dú)占修改Concurrent Hash Map中的數(shù)據(jù)。

另外,Java8中新增了一個Long Adder類,也是針對Java7以前的Atomic Long進(jìn)行的優(yōu)化,解決的是CAS類操作在高并發(fā)場景下,使用樂觀鎖思路,會導(dǎo)致大量線程長時間重復(fù)循環(huán)。Long Adder中也采用了類似的分段CAS操作,失敗則自動遷移到下一個分段進(jìn)行CAS的思路。

其實分布式鎖的優(yōu)化思路也是類似的,之前我們是在另外一個業(yè)務(wù)場景下落地了這個方案到生產(chǎn)中,不是在庫存超賣問題里用的。但是庫存超賣這個業(yè)務(wù)場景不錯,很容易理解,所以我們就用這個場景來說一下。

大家看下圖:

這就是分段加鎖。假如現(xiàn)在iPhone有1000個庫存,完全可以給拆成20個庫存段。

要是你愿意,可以在數(shù)據(jù)庫的表里建20個庫存字段,比如stock_01,stock_02,類似這樣的,也可以在Redis之類的地方放20個庫存Key。

總之,就是把你的1000件庫存給他拆開,每個庫存段是50件庫存,比如stock_01對應(yīng)50件庫存,stock_02對應(yīng)50件庫存。

接著,每秒1000個請求過來了!此時可以自己寫一個簡單的隨機(jī)算法,每個請求都是隨機(jī)在20個分段庫存里,選擇一個進(jìn)行加鎖。

這樣同時可以有最多20個下單請求一起執(zhí)行,每個下單請求鎖了一個庫存分段,然后在業(yè)務(wù)邏輯里面,就對數(shù)據(jù)庫或者是Redis中的那個分段庫存進(jìn)行操作即可,包括查庫存→判斷庫存是否充足→扣減庫存。

這相當(dāng)于一個20毫秒,可以并發(fā)處理掉20個下單請求,那么1秒,也就可以依次處理掉20*50=1000個對iPhone的下單請求了。

一旦對某個數(shù)據(jù)做了分段處理之后,有一個坑大家一定要注意:就是如果某個下單請求,咔嚓加鎖,然后發(fā)現(xiàn)這個分段庫存里的庫存不足了。這時你得自動釋放鎖,然后立馬換下一個分段庫存,再次嘗試加鎖后嘗試處理。這個過程一定要實現(xiàn)。

6、分布式鎖并發(fā)優(yōu)化方案有什么不足?

最大的不足是很不方便,實現(xiàn)太復(fù)雜:

  • 首先,你得對一個數(shù)據(jù)分段存儲,一個庫存字段本來好好的,現(xiàn)在要分為20個庫存字段。

  • 其次,你在每次處理庫存的時候,還得自己寫隨機(jī)算法,隨機(jī)挑選一個分段來處理。

  • 最后,如果某個分段中的數(shù)據(jù)不足了,你還得自動切換到下一個分段數(shù)據(jù)去處理。

這個過程都是要手動寫代碼實現(xiàn)的,還是有點工作量。不過我們確實在一些業(yè)務(wù)場景里,因為用到了分布式鎖,然后又必須要進(jìn)行鎖并發(fā)的優(yōu)化,又進(jìn)一步用到了分段加鎖的技術(shù)方案,效果當(dāng)然是很好的了,一下子并發(fā)性能可以增長幾十倍。

該優(yōu)化方案的后續(xù)改進(jìn):以我們本文所說的庫存超賣場景為例,你要是這么玩,會把自己搞的很痛苦!再次強(qiáng)調(diào),我們這里的庫存超賣場景,僅僅只是作為演示場景而已。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
分布式鎖用Redis還是Zookeeper?
終極鎖實戰(zhàn):單JVM鎖+分布式鎖
這幾種常見的“分布式鎖”寫法,搞懂再也不怕面試官,安排
分布式鎖的幾種典型實現(xiàn)
Redis分布式鎖解決并發(fā)超賣問題
11 張圖深入理解分布式鎖原理
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服