最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

1、定時(shí)任務(wù)

2、秒殺搶購(gòu),防止庫(kù)存超賣的問題

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

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

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

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

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

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

(2)基于zookeeper  CP模式

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

(4)Redis框架 Redisson、RedisLock

要求:

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

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

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

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

一直不釋放鎖怎么辦?

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

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

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

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

如何解決呢?

采用zk的臨時(shí)順序節(jié)點(diǎn)

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

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

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

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

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

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

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

答:先拿setnx來爭(zhēng)搶鎖,搶到之后,再用expire命令給鎖加一個(gè)過期時(shí)間防止鎖忘記了釋放。

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

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

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

相關(guān)文章

  • 幾種常見的Java運(yùn)行時(shí)異常小結(jié)

    幾種常見的Java運(yùn)行時(shí)異常小結(jié)

    在Java編程語(yǔ)言中異常處理是一項(xiàng)關(guān)鍵的機(jī)制,它幫助開發(fā)者識(shí)別和修復(fù)程序運(yùn)行時(shí)可能出現(xiàn)的問題,下面這篇文章主要給大家介紹了幾種常見的Java運(yùn)行時(shí)異常的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-08-08
  • 解決IDEA JSP沒有代碼提示問題的幾種方法

    解決IDEA JSP沒有代碼提示問題的幾種方法

    這篇文章主要介紹了解決IDEA JSP沒有代碼提示問題的幾種方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • Spring事務(wù)失效的幾種原因

    Spring事務(wù)失效的幾種原因

    在日常編碼過程中常常涉及到事務(wù),在前兩天看到一篇文章提到了Spring事務(wù),那么在此總結(jié)下在Spring環(huán)境下事務(wù)失效的幾種原因.
    2020-09-09
  • java實(shí)現(xiàn)哈夫曼文件解壓縮

    java實(shí)現(xiàn)哈夫曼文件解壓縮

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)哈夫曼文件解壓縮,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • Java-ElementUi中的row-class-name使用

    Java-ElementUi中的row-class-name使用

    這篇文章主要介紹了Java-ElementUi中的row-class-name使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Java責(zé)任鏈設(shè)計(jì)模式實(shí)例分析

    Java責(zé)任鏈設(shè)計(jì)模式實(shí)例分析

    這篇文章主要介紹了Java責(zé)任鏈設(shè)計(jì)模式,結(jié)合實(shí)例形式詳細(xì)分析了Java責(zé)任鏈設(shè)計(jì)模式的原理與相關(guān)操作技巧,需要的朋友可以參考下
    2019-07-07
  • Java 線程同步詳解

    Java 線程同步詳解

    這篇文章主要給大家詳細(xì)介紹的是Java 線程同步的相關(guān)問題及代碼示例,有需要的小伙伴可以參考下
    2016-03-03
  • SpringBoot+SpringSecurity處理Ajax登錄請(qǐng)求問題(推薦)

    SpringBoot+SpringSecurity處理Ajax登錄請(qǐng)求問題(推薦)

    這篇文章主要介紹了SpringBoot+SpringSecurity處理Ajax登錄請(qǐng)求問題,本文給大家介紹的非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-12-12
  • java接口中的代理設(shè)計(jì)模式代碼時(shí)實(shí)踐

    java接口中的代理設(shè)計(jì)模式代碼時(shí)實(shí)踐

    這篇文章主要介紹了java接口中的代理設(shè)計(jì)模式代碼時(shí)實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • spring/springboot整合dubbo詳細(xì)教程

    spring/springboot整合dubbo詳細(xì)教程

    今天教大家如何使用spring/springboot整合dubbo,文中有非常詳細(xì)的圖文介紹及代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴有很好地幫助,需要的朋友可以參考下
    2021-05-05

最新評(píng)論

唐河县| 武乡县| 宝鸡市| 德保县| 浑源县| 平利县| 西丰县| 泰来县| 遵化市| 农安县| 泽库县| 贞丰县| 德兴市| 杨浦区| 南开区| 芜湖市| 泌阳县| 镶黄旗| 镇远县| 江川县| 宁都县| 芒康县| 桐城市| 巴南区| 壤塘县| 乌鲁木齐县| 即墨市| 安新县| 土默特右旗| 三江| 临城县| 崇信县| 神木县| 南涧| 沙雅县| 那坡县| 祁门县| 黔西| 华容县| 岱山县| 高碑店市|