欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java分布式鎖理論(redis、zookeeper))案例詳解

 更新時間:2024年01月12日 09:36:32   作者:尋獲與失落  
zookeeper有個節(jié)點路徑的概念,節(jié)點路徑不能重復(fù),保證了唯一性,這篇文章給大家介紹Java分布式鎖理論(redis、zookeeper)?案例詳解,感興趣的朋友跟隨小編一起看看吧

一、分布式鎖有哪些應(yīng)用場景?

1、定時任務(wù)

2、秒殺搶購,防止庫存超賣的問題

3、雙寫一致性協(xié)議

比如我們?yōu)榱烁呖捎眯源罱朔?wù)集群,分別是8080和8081,我們在項目中設(shè)立定時任務(wù),目的是每天晚上定時拉取用戶數(shù)據(jù),給每個人發(fā)送一些推薦短信。那么這會出現(xiàn)什么問題呢?8080和8081都有定時任務(wù),到半夜2點同時查詢數(shù)據(jù)庫,同時調(diào)用阿里云接口發(fā)短信,那么肯定會重復(fù),使用了分布式鎖,8080搶到鎖執(zhí)行定時任務(wù),那么8081就會阻塞不會執(zhí)行。

那么肯定會有人問,為什么不用synchronized鎖呢?

如果我們是單個項目,用synchronized鎖可以實現(xiàn),但我們用的是集群,synchronized是無法跨jvm的。

二、分布式鎖的實現(xiàn)方案

(1)基于數(shù)據(jù)庫實現(xiàn)——mysql行鎖

(2)基于zookeeper  CP模式

(3)基于redis setnx實現(xiàn)  AP模式

(4)Redis框架 Redisson、RedisLock

要求:

  • 保證一致性:zookeeper 實現(xiàn)分布式鎖
  • 保證可用性:redis實現(xiàn)分布式鎖

三、zookeeper實現(xiàn)分布式鎖

zookeeper有個節(jié)點路徑的概念,節(jié)點路徑不能重復(fù),保證了唯一性。

如圖,我有4個springboot項目,首先jvm1先搶到了資源,設(shè)置了zk的節(jié)點路徑/lockPath,這個操作就相當(dāng)于獲取到了鎖,這時其余三個jvm獲取鎖失敗進(jìn)行阻塞狀態(tài)。當(dāng)jvm1執(zhí)行任務(wù)完畢,調(diào)用close()關(guān)閉連接,zk自動刪除節(jié)點路徑釋放鎖,zk通知其余3個jvm節(jié)點,它們3個開始競爭鎖。

一直不釋放鎖怎么辦?

我們上面說的是正常理想情況,那么問題來了,如果jvm1一直不釋放鎖,該怎么辦?

可以采用續(xù)命設(shè)計(設(shè)置超時時間),續(xù)命多次如果業(yè)務(wù)還是沒有執(zhí)行完畢的情況下,則認(rèn)為該鎖超時應(yīng)該主動釋放該鎖,再將所有業(yè)務(wù)代碼回滾,防止其它jvm一直阻塞等待。

如何避免分布式鎖羊群效應(yīng)問題?

如圖可以看出,當(dāng)我們有100個jvm的時候,如果jvm1搶到了鎖,執(zhí)行完業(yè)務(wù)釋放了鎖,zk就要喚醒其余99個jvm,那喚醒這個操作成本是很高的。

如何解決呢?

采用zk的臨時順序節(jié)點。

我們現(xiàn)在有三個jvm,分別創(chuàng)建了三個臨時順序節(jié)點路徑,誰最小就獲取鎖成功,首先jvm1最小獲取鎖成功,jvm2和jvm3就阻塞,jvm2創(chuàng)建的臨時節(jié)點就去訂閱最小的/lockPath1,當(dāng)jvm1執(zhí)行完畢釋放鎖并刪除/lockPath1節(jié)點,那么現(xiàn)在/lockPath2就是最小的節(jié)點,獲取鎖成功。

其實就相當(dāng)于synchronized的公平鎖,jvm1、jvm2、jvm3依次按順序執(zhí)行,這樣我們就不用喚醒所有,jvm1節(jié)點消失,我只需要喚醒jvm2節(jié)點。

四、redis實現(xiàn)分布式鎖

如果不存在值,則返回1,如果存在,則返回0。

那也就是說,我jvm1先setnx返回1搶到了鎖,這時jvm2也setnx發(fā)現(xiàn)返回0,那就無法執(zhí)行業(yè)務(wù)。

當(dāng)我們執(zhí)行業(yè)務(wù)完成后,刪除此key就起到了釋放鎖的作用。

那么問題來了,一個老生常談的話題,如果jvm1一直不釋放鎖怎么辦?

答:先拿setnx來爭搶鎖,搶到之后,再用expire命令給鎖加一個過期時間防止鎖忘記了釋放。

但這樣還有問題,如果在setnx之后執(zhí)行expire之前進(jìn)程意外crash或者要重啟維護(hù)了,那該怎么解決?

答:我們可以使用lua腳本來使setnx+expire成為原子操作。

到此這篇關(guān)于Java分布式鎖理論(redis、zookeeper) 詳解的文章就介紹到這了,更多相關(guān)Java分布式鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺談springboot多模塊(modules)開發(fā)

    淺談springboot多模塊(modules)開發(fā)

    這篇文章主要介紹了淺談springboot多模塊(modules)開發(fā),詳細(xì)的介紹了springboot多模塊的實現(xiàn),有興趣的可以了解一下
    2017-09-09
  • spring boot 中設(shè)置默認(rèn)網(wǎng)頁的方法

    spring boot 中設(shè)置默認(rèn)網(wǎng)頁的方法

    這篇文章主要介紹了spring boot 中設(shè)置默認(rèn)網(wǎng)頁的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • 詳解如何把cmd黑窗口把java文件打包成jar

    詳解如何把cmd黑窗口把java文件打包成jar

    本文主要介紹了如何把cmd黑窗口把java文件打包成jar,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • SpringBoot 使用hibernate validator校驗

    SpringBoot 使用hibernate validator校驗

    這篇文章主要介紹了SpringBoot 使用hibernate validator校驗,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • SpringBoot?MongoCustomConversions自定義轉(zhuǎn)換方式

    SpringBoot?MongoCustomConversions自定義轉(zhuǎn)換方式

    這篇文章主要介紹了SpringBoot?MongoCustomConversions自定義轉(zhuǎn)換方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Java線程調(diào)度之線程休眠用法分析

    Java線程調(diào)度之線程休眠用法分析

    這篇文章主要介紹了Java線程調(diào)度之線程休眠用法,較為詳細(xì)的分析了Java線程休眠的功能與實現(xiàn)技巧,需要的朋友可以參考下
    2015-06-06
  • idea插件無法下載4的種解決方式

    idea插件無法下載4的種解決方式

    這篇文章主要介紹了idea插件無法下載4的種解決方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Java?windows環(huán)境構(gòu)建圖文教程

    Java?windows環(huán)境構(gòu)建圖文教程

    這篇文章主要為大家介紹了Java?windows環(huán)境構(gòu)建圖文教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>
    2023-12-12
  • Java tomcat手動配置servlet詳解

    Java tomcat手動配置servlet詳解

    這篇文章主要為大家介紹了tomcat手動配置servlet,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-11-11
  • SpringBoot Bean被加載時進(jìn)行控制

    SpringBoot Bean被加載時進(jìn)行控制

    很多時候我們需要根據(jù)不同的條件在容器中加載不同的Bean,或者根據(jù)不同的條件來選擇是否在容器中加載某個Bean,這就是Bean的加載控制,一般我們可以通過編程式或注解式兩種不同的方式來完成Bean的加載控制
    2023-02-02

最新評論