Spring Boot 2实现分布式锁

2,856 阅读2分钟

Spring Boot 2实现分布式锁

分布式锁在分布式环境中是必不可少的,通常见到的分布式锁实现方式有Mysql、zk、redis,最近我发现了Spring Integration中已经集成了分布式锁。

RedisLockRegistry 是什么?

RedisLockRegistry是spring-integration-redis中提供redis分布式锁实现类。主要是通过redis锁+本地锁双重锁的方式实现的一个比较好的锁。

RedisLockRegistry 支持的类型

  • Gemfire
  • JDBC
  • Redis
  • Zookeeper

基于redis的分布式锁的使用

添加依赖
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.integration</groupId>
  <artifactId>spring-integration-redis</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
redis连接配置
## redis
# Redis数据库索引
spring.redis.database=0
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=page
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=10000
初始化RedisLockRegistry
@Configuration
public class RedisLockConfiguration {
  @Bean
  public RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory) {
    return new RedisLockRegistry(redisConnectionFactory, "my-lock");
  }
}

具体使用参考:org.springframework.integration.redis.util.RedisLockRegistry

使用
@RestController
@Slf4j
public class RedislockController {
    @Resource
    private RedisLockRegistry redisLockRegistry;

    @GetMapping("/lock")
    public JSONObject lock(@RequestParam("lockKey") String lockKey) {
        log.info("lockKey={}", lockKey);
        Lock lock = redisLockRegistry.obtain(lockKey);
        JSONObject result = new JSONObject();
        try {
            boolean getLock = lock.tryLock(3, TimeUnit.SECONDS);
            log.info("{}-{}获取锁={}", Thread.currentThread(),new SimpleDateFormat("HH:mm:ss.S").format(new Date()), getLock);
            TimeUnit.SECONDS.sleep(5);
            //TODO 具体业务
        } catch (Exception e) {
            log.error("获取锁失败={}", Throwables.getStackTraceAsString(e));
            result.put("msg", "获取锁失败");
        } finally {
            log.info("{}-{}释放锁", Thread.currentThread(),new SimpleDateFormat("HH:mm:ss.S").format(new Date()));
            lock.unlock();
        }
        return result;
    }
}

相关文章