成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Spring自帶分布式鎖你用過嗎?

云計算 分布式
Spring Integration 的分布式鎖為開發者提供了一種在分布式系統中實現可靠同步的有效方法。通過合理選擇和使用這些鎖實現,可以確保對共享資源的訪問在多個節點之間保持協調一致,從而提高系統的整體可靠性和性能。

環境:SpringBoot2.7.12

本篇文章將會為大家介紹有關spring integration提供的分布式鎖功能。

1. 簡介

Spring Integration 是一個框架,用于構建事件驅動的應用程序。在 Spring Integration 中,LockRegistry 是一個接口,用于管理分布式鎖。分布式鎖是一種同步機制,用于確保在分布式系統中的多個節點之間對共享資源的互斥訪問。

LockRegistry及相關子接口(如:RenewableLockRegistry) 接口的主要功能:

  • 獲取鎖:當應用程序需要訪問共享資源時,它可以通過 LockRegistry 獲取一個鎖。
  • 釋放鎖:當應用程序完成對共享資源的訪問后,它應該釋放鎖,以便其他應用程序可以獲取它(第一點中提到,并沒有提供直接釋放鎖的操作,而是內部自動完成)。
  • 續期:提供續期機制,以便在需要時延長鎖的持有時間。

常見的 LockRegistry 實現包括基于數據庫、ZooKeeper 和 Redis 的實現。

公共依賴

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-integration</artifactId>
</dependency>

2. 基于數據庫分布式鎖

引入依賴

<dependency>
  <groupId>org.springframework.integration</groupId>
  <artifactId>spring-integration-jdbc</artifactId>
</dependency>
<dependency>
  <groupId>com.zaxxer</groupId>
  <artifactId>HikariCP</artifactId>
  <scope>compile</scope>
</dependency>
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>8.0.30</version>
</dependency>

配置

spring:
  datasource:
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/spring_lock?serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&useSSL=false
    username: root
    password: xxxooo
    type: com.zaxxer.hikari.HikariDataSource
    hikari:
      minimumIdle: 10
      maximumPoolSize: 200
---
spring:
  integration:
    jdbc:
      initialize-schema: always
      # 基于數據庫需要執行初始化腳本
      schema: classpath:schema-mysql.sql

注冊核心Bean對象

@Bean
public DefaultLockRepository defaultLockRepository(DataSource dataSource) {
  DefaultLockRepository lockRepository = new DefaultLockRepository(dataSource);
  // 這里根據你的業務需要,配置表前綴,默認:IN_
  lockRepository.setPrefix("T_") ;
  return lockRepository ;
}


// 注冊基于數據庫的分布式鎖
@Bean
public JdbcLockRegistry jdbcLockRegistry(DefaultLockRepository lockRepository) {
  return new JdbcLockRegistry(lockRepository) ;
}

測試用例

@Test
public void testLock() throws Exception
  int len = 10 ;
  CountDownLatch cdl = new CountDownLatch(len) ;
  CountDownLatch waiter = new CountDownLatch(len) ;
  Thread[] ts = new Thread[len] ;
  for (int i = 0; i < len; i++) {
    ts[i] = new Thread(() -> {
      waiter.countDown() ;
      System.out.println(Thread.currentThread().getName() + " - 準備獲取鎖") ;
      try {
        waiter.await() ;
      } catch (InterruptedException e1) {
        e1.printStackTrace();
      }
      // 獲取鎖
      Lock lock = registry.obtain("drug_store_key_001") ;
      lock.lock() ;
      System.out.println(Thread.currentThread().getName() + " - 獲取鎖成功") ;
      try {
        try {
          TimeUnit.SECONDS.sleep(2) ;
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      } finally {
        // 釋放鎖
        lock.unlock() ;
        cdl.countDown() ;
        System.out.println(Thread.currentThread().getName() + " - 鎖釋放成功") ;
      }
    }, "T - " + i) ;
  }
  for (int i = 0; i < len; i++) {
    ts[i].start() ; 
  }
  cdl.await() ;
}

數據庫

圖片圖片

鎖的實現JdbcLock,該對象實現了java.util.concurrent.locks.Lock,所以該鎖是支持重入等操作的。

配置鎖獲取失敗后的重試間隔,默認值100ms

JdbcLockRegistry jdbcLockRegistry = new JdbcLockRegistry(lockRepository);
// 定義鎖對象時設置當獲取鎖失敗后重試間隔時間。
jdbcLockRegistry.setIdleBetweenTries(Duration.ofMillis(200)) ;

鎖續期

jdbcLockRegistry.renewLock("drug_store_key_001");

3. 基于Redis分布式鎖

引入依賴

<dependency>
  <groupId>org.springframework.integration</groupId>
  <artifactId>spring-integration-jdbc</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

配置

spring:
  redis:
    host: localhost
    port: 6379
    password: xxxooo
    database: 8
    lettuce:
      pool:
        maxActive: 8
        maxIdle: 100
        minIdle: 10
        maxWait: -1

測試用例

測試代碼與上面基于JDBC的一樣,只需要修改調用加鎖的代碼即可

Lock lock = redisLockRegistry.obtain("001") ;

設置鎖的有效期,默認是60s

// 第三個參數設置了key的有效期,這里改成10s
RedisLockRegistry redisLockRegistry = new RedisLockRegistry(connectionFactory, registryKey, 10000) ;

注意:redis key的有效期設置為10s,如果你的業務執行超過了10s,那么程序將會報錯。并沒有redission watch dog機制。

Exception in thread "T - 0" java.lang.IllegalStateException: Lock was released in the store due to expiration. The integrity of data protected by this lock may have been compromised.
  at org.springframework.integration.redis.util.RedisLockRegistry$RedisLock.unlock(RedisLockRegistry.java:450)
  at com.pack.SpringIntegrationDemoApplicationTests.lambda$1(SpringIntegrationDemoApplicationTests.java:83)
  at java.lang.Thread.run(Thread.java:748)

如果10s過期后key自動刪除后,其它線程是否能立馬獲取到鎖呢?如果是單節點中其它現在也不能獲取鎖,必須等上一個線程結束后才可以,這是因為在內部還維護了一個ReentrantLock鎖,在獲取分布式鎖前要先獲取本地的一個鎖。

private abstract class RedisLock implements Lock {
  private final ReentrantLock localLock = new ReentrantLock();
  public final void lock() {
      this.localLock.lock();
      while (true) {
        try {
          if (tryRedisLock(-1L)) {
            return;
          }
        } catch (InterruptedException e) {
        } catch (Exception e) {
          this.localLock.unlock();
          rethrowAsLockException(e);
        }
      }
    }
}

注意:不管是基于數據庫還是Redis都要先獲取本地的鎖

Spring Cloud Task就使用到了Spring Integration中的鎖基于數據庫的。

總結:Spring Integration 的分布式鎖為開發者提供了一種在分布式系統中實現可靠同步的有效方法。通過合理選擇和使用這些鎖實現,可以確保對共享資源的訪問在多個節點之間保持協調一致,從而提高系統的整體可靠性和性能。

完畢!!!

責任編輯:武曉燕 來源: Spring全家桶實戰案例源碼
相關推薦

2021-10-09 11:34:59

MySQL分布式鎖庫存

2024-04-26 08:06:58

分布式系統

2023-09-26 08:16:25

分布式鎖數據庫

2022-07-06 08:01:05

數據庫分布式

2019-06-19 15:40:06

分布式鎖RedisJava

2020-07-15 16:50:57

Spring BootRedisJava

2016-11-02 12:06:27

分布式系統大數據

2021-07-26 11:09:46

Redis分布式技術

2022-05-18 10:38:51

Redis分布式鎖數據

2018-07-17 08:14:22

分布式分布式鎖方位

2019-02-26 09:51:52

分布式鎖RedisZookeeper

2021-07-16 07:57:34

ZooKeeperCurator源碼

2022-08-04 08:45:50

Redisson分布式鎖工具

2023-09-09 12:23:24

函數式接口程序

2018-11-27 16:17:13

分布式Tomcat

2021-11-26 06:43:19

Java分布式

2023-08-21 19:10:34

Redis分布式

2023-09-22 08:00:00

分布式鎖Redis

2017-10-24 11:28:23

Zookeeper分布式鎖架構

2022-01-06 10:58:07

Redis數據分布式鎖
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美性video 精品亚洲一区二区 | 国产高清在线精品一区二区三区 | 91亚洲国产 | 久久久tv| 国产91视频播放 | 日韩欧美亚洲 | 九九九视频在线 | av一区二区三区 | 欧美自拍一区 | 欧美日韩专区 | 国产欧美一区二区三区另类精品 | 中国一级特黄真人毛片 | 亚洲综合色网站 | 中文字幕日韩一区 | 日本高清在线一区 | 91久久久久久久 | 亚洲欧美一区二区三区国产精品 | 中文在线a在线 | 久久精品一区二区 | 自拍视频网站 | 高清国产一区二区 | 午夜精品在线 | 99亚洲精品 | 日韩精品激情 | 国产一区二区在线免费视频 | 久久久久成人精品免费播放动漫 | 高清一区二区三区 | 国产精品国产亚洲精品看不卡15 | 欧美精品一区二区在线观看 | 久久亚洲国产精品日日av夜夜 | 国产精品视频网 | 国产一区二区三区四区五区3d | 美女精品一区 | 亚洲精品一区中文字幕乱码 | 国产美女一区二区 | 日韩欧美中文字幕在线观看 | 欧美一区二区 | 草久视频 | 国产欧美一区二区三区日本久久久 | 亚洲精品日韩一区二区电影 | 欧区一欧区二欧区三免费 |