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

SpringBoot integration實現(xiàn)分布式鎖的示例詳解

 更新時間:2023年12月11日 08:07:35   作者:zooooooooy  
常規(guī)項目都是采用Redission來實現(xiàn)分布式鎖,進(jìn)行分布式系統(tǒng)中資源競爭加鎖操作,偶然發(fā)現(xiàn)SpringBoot中的integration也實現(xiàn)多種載體的分布式鎖控制,下面我們就來看看具體實現(xiàn)方法吧

常規(guī)項目都是采用Redission來實現(xiàn)分布式鎖,進(jìn)行分布式系統(tǒng)中資源競爭加鎖操作。需要單獨引入Jar包,偶然發(fā)現(xiàn)SpringBoot中的integration也實現(xiàn)多種載體的分布式鎖控制。

代碼集成

引入

// 分布式鎖
implementation 'org.springframework.boot:spring-boot-starter-integration'
implementation('org.springframework.integration:spring-integration-redis')

采用最常見的redis來作為分布式鎖的底層載體。

鎖注冊

@Configuration配置類中,添加分布式鎖注冊信息。

@Bean
open fun redisLockRegistry(redisConnectionFactory: RedisConnectionFactory): RedisLockRegistry {

    return RedisLockRegistry(redisConnectionFactory, "fcDistroLock", 20000L)
}

有兩個核心參數(shù),第一個指定的是分布式鎖的前綴,第二個是指定分布式鎖的過期時間。過期時間建議不要指定到過長,防止拖慢整體的業(yè)務(wù)響應(yīng)速度。

加鎖

在使用之前需要知道加鎖的三個核心方法。

lock直接加鎖,一直等待
tryLock(無參數(shù))嘗試加鎖,未獲取到鎖,直接返回失敗
tryLock(long time, TimeUnit unit)嘗試加鎖,等待一定時間后未獲取到鎖,直接返回失敗

建議使用帶參數(shù)的嘗試加鎖,設(shè)置一個合適的超時時間。建議使用模式如下

Lock lock = ...;
if (lock.tryLock(time)) {
  try {
    // manipulate protected state
  } finally {
    lock.unlock();
  }
} else {
  // perform alternative actions
}}

有一個點需要注意,當(dāng)加鎖失敗時,需要考慮補(bǔ)償機(jī)制。例如用戶余額扣減失敗,需要重新進(jìn)行推送;或者加鎖失敗,拋出異?;貪L本地事務(wù)等。

使用上非常簡單。

細(xì)粒度加鎖

可以通過上圖可以看到,我們加鎖的對象是用戶id,并不是所有用戶。代表不同用戶之間操作是不受分布式事務(wù)限制。這里同步會衍生另外一個問題,如果用戶id特別多,就會占用非常多的資源。這里就需要定時手動清除加鎖對象,或者加鎖成功后直接清除。個人建議使用定時清除,有助于減少對象的創(chuàng)建,提高系統(tǒng)吞吐量。

@Scheduled(cron = "0 0 0/1 * * ?")
fun scheduleRemoveRedisLock() {

    redisLockRegistry.expireUnusedOlderThan(1000 * 60 * 60)
}

RedisLockRegistry其實已經(jīng)提供清除的方法,我們只需要指定清除的有效期即可。項目中指定的是清除1個小時之前的加鎖對象。

核心邏輯

打開tryLock的實現(xiàn)類RedisLock很容易發(fā)現(xiàn),每個加鎖id都對應(yīng)1個RedisLock,1個RedisLock中包含1個ReentrantLock,用來進(jìn)行本地資源互斥。

public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
   long now = System.currentTimeMillis();
   if (!this.localLock.tryLock(time, unit)) { // 獲取本地互斥鎖
      return false;
   }
   try {
      long expire = now + TimeUnit.MILLISECONDS.convert(time, unit);
      boolean acquired;
      while (!(acquired = obtainLock()) && System.currentTimeMillis() < expire) { //NOSONAR
         Thread.sleep(100); //NOSONAR 防止請求過快,進(jìn)行100Ms的休眠
      }
      if (!acquired) {
         this.localLock.unlock();
      }
      return acquired;
   }
   catch (Exception e) {
      this.localLock.unlock();
      rethrowAsLockException(e);
   }
   return false;
}

兩個條件跳出循環(huán)獲取鎖的過程。

  • 超過等待時間
  • redis返回是否獲取到鎖

Redis鎖邏輯判斷

private static final String OBTAIN_LOCK_SCRIPT =
      "local lockClientId = redis.call('GET', KEYS[1])\n" +
            "if lockClientId == ARGV[1] then\n" +
            "  redis.call('PEXPIRE', KEYS[1], ARGV[2])\n" +
            "  return true\n" +
            "elseif not lockClientId then\n" +
            "  redis.call('SET', KEYS[1], ARGV[1], 'PX', ARGV[2])\n" +
            "  return true\n" +
            "end\n" +
            "return false";

利用Redis的原子性進(jìn)行鎖資源判斷,通過是否相同應(yīng)用id來支持重入鎖。

整體使用

使用上非常簡單,沒有鎖續(xù)期,沒有讀寫鎖,也沒有考慮重入鎖的計數(shù)問題。功能上還是比Redission差不少,在一些業(yè)務(wù)相對比較簡單的場景可以嘗試使用SpringBoot自帶的分布式鎖。如果需要面對更細(xì)粒度的控制,提高性能,更復(fù)雜的鎖控制,就需要使用到Redission來進(jìn)行分布式鎖的編寫了。

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

相關(guān)文章

  • Maven和IntelliJ IDEA搭建多模塊微服務(wù)的實現(xiàn)

    Maven和IntelliJ IDEA搭建多模塊微服務(wù)的實現(xiàn)

    本文主要介紹了Maven和IntelliJ IDEA搭建多模塊微服務(wù)的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • MyBatis-Plus標(biāo)簽@TableField之fill自動填充方式

    MyBatis-Plus標(biāo)簽@TableField之fill自動填充方式

    這篇文章主要介紹了MyBatis-Plus標(biāo)簽@TableField之fill自動填充方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • springboot多數(shù)據(jù)源配合docker部署mysql主從實現(xiàn)讀寫分離效果

    springboot多數(shù)據(jù)源配合docker部署mysql主從實現(xiàn)讀寫分離效果

    這篇文章主要介紹了springboot多數(shù)據(jù)源配合docker部署mysql主從實現(xiàn)讀寫分離,通過使用docker獲取mysql鏡像,具體內(nèi)容詳情跟隨小編一起看看吧
    2021-09-09
  • java編程之AC自動機(jī)工作原理與實現(xiàn)代碼

    java編程之AC自動機(jī)工作原理與實現(xiàn)代碼

    這篇文章主要介紹了java編程之AC自動機(jī)的有關(guān)內(nèi)容,涉及其應(yīng)用場景,運行原理,運行過程,構(gòu)造方法及Java中的實現(xiàn)代碼,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • 一文詳解SpringBoot響應(yīng)壓縮功能的配置與優(yōu)化

    一文詳解SpringBoot響應(yīng)壓縮功能的配置與優(yōu)化

    Spring Boot的響應(yīng)壓縮功能基于智能協(xié)商機(jī)制,需同時滿足很多條件,本文主要為大家詳細(xì)介紹了SpringBoot響應(yīng)壓縮功能的配置與優(yōu)化,需要的可以參考下
    2025-03-03
  • Spring?Security安全框架之記住我功能

    Spring?Security安全框架之記住我功能

    這篇文章主要介紹了Spring?Security安全框架之記住我,本次就來探究如何實現(xiàn)這種自動登錄、記住我的功能,通過實例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-02-02
  • java8升級java21方法步驟(完整pom文件升級及代碼修改)

    java8升級java21方法步驟(完整pom文件升級及代碼修改)

    在從Java?8升級至Java?211的過程中,需要對多個POM文件進(jìn)行升級,涉及parent、web、service等模塊,文中通過代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用java具有一定的參考借鑒價值,需要的朋友可以參考下
    2024-11-11
  • Java中SPI的一些理解

    Java中SPI的一些理解

    這篇文章主要介紹了Java中SPI的一些理解,幫助大家更好的理解和學(xué)習(xí)Java的相關(guān)知識,感興趣的朋友可以了解下
    2020-12-12
  • Java中提供synchronized后為什么還要提供Lock

    Java中提供synchronized后為什么還要提供Lock

    這篇文章主要介紹了Java中提供synchronized后為什么還要提供Lock,在Java中提供了synchronized關(guān)鍵字來保證只有一個線程能夠訪問同步代碼塊,下文更多相關(guān)資料需要的小伙伴可以參考一下
    2022-03-03
  • Spring Boot 配置隨機(jī)數(shù)的技巧代碼詳解

    Spring Boot 配置隨機(jī)數(shù)的技巧代碼詳解

    這篇文章主要介紹了Spring Boot 配置隨機(jī)數(shù)技巧,spring boot 支持在系統(tǒng)加載的時候配置隨機(jī)數(shù),具體實例代碼大家參考下本文
    2018-05-05

最新評論

右玉县| 衡水市| 布尔津县| 桂林市| 东至县| 山西省| 宁都县| 东兴市| 宁南县| 嘉义市| 元江| 招远市| 揭西县| 武宣县| 福泉市| 宜良县| 紫阳县| 康定县| 昌宁县| 吉安县| 诸暨市| 七台河市| 永修县| 颍上县| 青冈县| 双柏县| 蒙城县| 黄陵县| 普宁市| 乳源| 北流市| 南阳市| 洪洞县| 祥云县| 扎兰屯市| 合作市| 罗田县| 海兴县| 呈贡县| 荃湾区| 菏泽市|