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

單機(jī)redis分布式鎖實(shí)現(xiàn)原理解析

 更新時(shí)間:2020年04月26日 09:45:36   作者:Ayato  
這篇文章主要介紹了單機(jī)redis分布式鎖實(shí)現(xiàn)原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

最近我們有個(gè)服務(wù)經(jīng)常出現(xiàn)存儲(chǔ)的數(shù)據(jù)出現(xiàn)重復(fù),首先上一個(gè)系統(tǒng)流程圖:

用戶(hù)通過(guò)http請(qǐng)求可以通知任務(wù)中心結(jié)束掉自己發(fā)送的任務(wù),這時(shí)候任務(wù)中心會(huì)通過(guò)MQ通知結(jié)束服務(wù)去結(jié)束任務(wù)保存數(shù)據(jù),由于任務(wù)結(jié)束數(shù)據(jù)計(jì)算保存有一定延時(shí),所以存在用戶(hù)短時(shí)間內(nèi)多次結(jié)束同一個(gè)任務(wù),這時(shí)候就會(huì)導(dǎo)致我們結(jié)束服務(wù)對(duì)同一個(gè)任務(wù)保存多次數(shù)據(jù)。恰好我們也是用了redis,所以對(duì)于這個(gè)問(wèn)題我當(dāng)時(shí)想到使用分布式鎖來(lái)解決,那么如何用redis實(shí)現(xiàn)分布式鎖呢?

首先要明確一個(gè)分布式鎖應(yīng)具備的原則:

互斥性。在任意時(shí)刻,只有一個(gè)客戶(hù)端能持有鎖;不會(huì)發(fā)生死鎖。即使一個(gè)客戶(hù)端持有鎖的期間崩潰而沒(méi)有主動(dòng)釋放鎖,也需要保證后續(xù)其他客戶(hù)端能夠加鎖成功;加鎖和解鎖必須是同一個(gè)客戶(hù)端;有高可用的獲取鎖和釋放鎖功能。

由于我們只使用了單機(jī)的redis,所以本文的實(shí)現(xiàn)不具備第四點(diǎn)原則。

我們這個(gè)鎖的實(shí)現(xiàn)就包括兩點(diǎn):加鎖、解鎖。首先看加鎖。先上代碼:

public boolean tryGetDistributedLock(String lockKey, String requestId, int expireTime) throws Exception{
    Jedis jedis = null;
    try {
      jedis = getJedisClient();
      String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
      if (LOCK_SUCCESS.equals(result)) {
        return true;
      }
      return false;
    } finally {
      returnResource(jedis);
    }
 }

我們的加鎖就是設(shè)置一個(gè)鍵值對(duì),并且滿(mǎn)足以下條件:

確保只有當(dāng)鍵不存在時(shí)才設(shè)置有效;設(shè)置的值必須是當(dāng)前客戶(hù)端生成的uuid;鍵必須要有過(guò)期時(shí)間。

這三點(diǎn)條件就可以滿(mǎn)足上述的原則1、原則2。

接下來(lái)看下解鎖,代碼如下:

public boolean releaseDistributedLock(String lockKey, String requestId) throws Exception{
    Jedis jedis = null;
    try {
      jedis = getJedisClient();
      String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
      Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
      if (RELEASE_SUCCESS.equals(result)) {
        return true;
      }
      return false;
    }finally {
      returnResource(jedis);
    }
}

解鎖是通過(guò)一段lua腳本實(shí)現(xiàn),邏輯如下:

1、獲取鎖鍵值看是否與當(dāng)初設(shè)置的值一致;

2、如果一致則刪除鍵。

由于解鎖過(guò)程分為兩步,為了確保原子性所以通過(guò)讓redis執(zhí)行l(wèi)ua腳本來(lái)實(shí)現(xiàn),校驗(yàn)鍵值可以確保加鎖解鎖都是同一個(gè)客戶(hù)端。

這樣一個(gè)簡(jiǎn)易的分布式鎖就實(shí)現(xiàn)完畢了,當(dāng)然在本文開(kāi)頭就說(shuō)了,這個(gè)實(shí)現(xiàn)只能滿(mǎn)足單機(jī)redis的情況,對(duì)于redis集群其實(shí)是不嚴(yán)謹(jǐn)?shù)模瑢?duì)于redis集群有一個(gè)redlock方案,我也在研究中,后面也會(huì)總結(jié)一下。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • ExecutorService Callable Future多線程返回結(jié)果原理解析

    ExecutorService Callable Future多線程返回結(jié)果原理解析

    這篇文章主要為大家介紹了ExecutorService Callable Future多線程返回結(jié)果,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • jdbc與druid連接池的使用詳解

    jdbc與druid連接池的使用詳解

    這篇文章主要介紹了jdbc與druid連接池的使用詳解,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • java獲取當(dāng)前時(shí)間和前一天日期(實(shí)現(xiàn)代碼)

    java獲取當(dāng)前時(shí)間和前一天日期(實(shí)現(xiàn)代碼)

    java獲取當(dāng)前時(shí)間和前一天日期的實(shí)現(xiàn)代碼。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助
    2013-10-10
  • java使用poi導(dǎo)出Excel的方法

    java使用poi導(dǎo)出Excel的方法

    這篇文章主要為大家詳細(xì)介紹了java使用poi導(dǎo)出Excel的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • 解決mybatis 執(zhí)行mapper的方法時(shí)報(bào)空指針問(wèn)題

    解決mybatis 執(zhí)行mapper的方法時(shí)報(bào)空指針問(wèn)題

    這篇文章主要介紹了解決mybatis 執(zhí)行mapper的方法時(shí)報(bào)空指針問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • springboot中RabbitMQ死信隊(duì)列的實(shí)現(xiàn)示例

    springboot中RabbitMQ死信隊(duì)列的實(shí)現(xiàn)示例

    死信隊(duì)列是一種特殊的消息隊(duì)列,用來(lái)存儲(chǔ)無(wú)法被正常消費(fèi)的消息,常被用來(lái)實(shí)現(xiàn)延遲處理,異常消息處理等,本文主要介紹了springboot中RabbitMQ死信隊(duì)列的實(shí)現(xiàn)示例,感興趣的可以了解一下
    2024-01-01
  • Spring中網(wǎng)絡(luò)請(qǐng)求客戶(hù)端WebClient的使用詳解

    Spring中網(wǎng)絡(luò)請(qǐng)求客戶(hù)端WebClient的使用詳解

    作為替代,Spring 官方已在 Spring 5 中引入了 WebClient 作為非阻塞式 Reactive HTTP 客戶(hù)端,本文將通過(guò)樣例演示如何使用 WebClient,希望對(duì)大家有所幫助
    2024-04-04
  • Java 中的語(yǔ)法糖,真甜

    Java 中的語(yǔ)法糖,真甜

    語(yǔ)法糖(Syntactic sugar),也叫做糖衣語(yǔ)法,是英國(guó)科學(xué)家發(fā)明的一個(gè)術(shù)語(yǔ),通常來(lái)說(shuō)使用語(yǔ)法糖能夠增加程序的可讀性,從而減少程序代碼出錯(cuò)的機(jī)會(huì).這篇文章主要介紹了Java 中的語(yǔ)法糖知識(shí),需要的朋友可以參考下
    2020-12-12
  • springboot使用AOP+反射實(shí)現(xiàn)Excel數(shù)據(jù)的讀取

    springboot使用AOP+反射實(shí)現(xiàn)Excel數(shù)據(jù)的讀取

    本文主要介紹了springboot使用AOP+反射實(shí)現(xiàn)Excel數(shù)據(jù)的讀取,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Java對(duì)類(lèi)私有變量的暴力反射技術(shù)講解

    Java對(duì)類(lèi)私有變量的暴力反射技術(shù)講解

    今天小編就為大家分享一篇關(guān)于Java對(duì)類(lèi)私有變量的暴力反射技術(shù)講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-03-03

最新評(píng)論