Springboot + redis分布式锁

1.引入redis和redisson

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

<!--        redisson-->
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.16.4</version>
        </dependency>

 

2.配置一下

application.yml里面加上 redisson配置文件

redisson:
  config: classpath:redisson.yaml

新建一个redisson.yaml  填一些redis配置

singleServerConfig:
  # Redis 服务器的地址
  address: "redis://127.0.0.1:6379"
  # 连接池的大小
  connectionPoolSize: 64
  # Redis 数据库索引
  database: 0
  # 超时时间,单位为毫秒
  timeout: 3000
  # Redis 命令失败重试次数
  retryAttempts: 3
  # 两次命令之间重试的时间间隔,单位为毫秒
  retryInterval: 1500
  # 发布和订阅的连接的最小数量
  subscriptionConnectionMinimumIdleSize: 1
  # 发布和订阅的连接池的大小
  subscriptionConnectionPoolSize: 50
  # 当前处理 Redis 命令的线程共享的联接
  connectionMinimumIdleSize: 10

 

redisson还要一个配置类:

@Configuration
public class RedissonConfig {

    @Bean(destroyMethod = "shutdown")
    public RedissonClient redissonClient() {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://localhost:6379");
        return Redisson.create(config);
    }
}

 

这样配置完基本上ok了,然后就可以直接 lock  , unlock 来进行获取锁和释放锁的操作。

 

3.实践

下面这个场景是模拟 做一个用户匹配的操作,例如相亲配对用户,某用户很热门,许多用户争抢匹配,但是该用户只有一个,防止出现超匹配的问题,就要进行上锁

//   注入Redisson
    @Autowired
    private RedissonClient redissonClient;

    @Override
    public User matchId(Integer id) {
        RLock lock = redissonClient.getLock("lock_" + id);
        try {
            if (lock.tryLock()) {
                // 获取锁成功,执行业务逻辑
                User user = userMapper.selectById(id);
                if (user != null) {
                    // 执行匹配逻辑
                    // ...
                    System.out.println("匹配成功");
                    return user;
                } else {
                    System.out.println("用户不匹配或已被匹配");
                }
            }
//            锁被其他人占用着
            else {
                System.out.println("匹配请求处理中,请稍后再试");
            }
        } catch (Exception e) {
            Thread.currentThread().interrupt();
            System.out.println("匹配请求被中断");
        } finally {
            // 释放锁
            lock.unlock();
        }
        return null;
    }

 

上面的还是一个单节点redis的操作,如果要部署集群redis的话,就可以用上 redlock的方法,

保证集群的全部节点都来管理同一个锁的状态,防止某个上锁的节点突然崩溃了,然后其它某个节点是没上锁的状态,就可以进行多次匹配的问题

posted @ 2024-03-31 22:32  Hello霖  阅读(187)  评论(1编辑  收藏  举报