redis-RedisLockRegistry 分布式锁

对于分布式服务的情况下,当只使用java原生相关锁(ReentrantLock)操作时,只能保证一个jvm进程中的操作受到锁的保护,但对于多个jvm进程就无法进行有效锁保护控制;

因此为了满足分布式场景, 需要使用一个统一管理位置,因此通过redis 来做作为锁控制 

spring 提供的redis支持

https://docs.spring.io/spring-integration/reference/html/redis.html#redis-lock-registry

其利用java 本地锁和 redis SET相关指令 双重保证

 

引入相关组件

<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>

 

在application.yml中添加redis的配置

spring:
  redis:
    host: localhost # Redis服务器地址
    database: 0 # Redis数据库索引(默认为0)
    port: 6379 # Redis服务器连接端口
    password: # Redis服务器连接密码(默认为空)

  

建立配置类,注入RedisLockRegistry

@Configuration
public class RedisLockConfiguration {

    @Bean
    public RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory) {
        return new RedisLockRegistry(redisConnectionFactory, "redis-lock");
    }

}

  

@RestController
@Api(tags = "RedisLockRegistryController")
@RequestMapping("/redisLockRegistry")
@Slf4j
public class RedisLockRegistryController {

    @Resource
    private RedisLockRegistry redisLockRegistry;

    @ApiOperation("加锁")
    @GetMapping(value = "/tryGetDistributedLock")
    public void tryGetDistributedLock(@RequestParam String key, @RequestParam String value) {
        Lock lock = redisLockRegistry.obtain("redis");
        try {
            //尝试在指定时间内加锁,如果已经有其他锁锁住,获取当前线程不能加锁,则返回false,加锁失败;加锁成功则返回true
            if (lock.tryLock(3, TimeUnit.SECONDS)) {
                log.info("lock is ready");
                TimeUnit.SECONDS.sleep(5);
            }
        } catch (InterruptedException e) {
            log.error("obtain lock error", e);
        } finally {
            lock.unlock();
        }
    }

}

  

 

测试 启动多个实例,分别访问/lock/redis 端点,一个正常秩序业务逻辑,另外一个实例访问出现如下错误,说明第二个实例没有拿到锁,证明了分布式锁的存在。

 

posted @ 2022-01-05 18:53  草木物语  阅读(1620)  评论(0编辑  收藏  举报