redisson实现分布式锁(集群环境)

问题引入

面对高并发时,mysql事务无法保证原子性,可以使用synchronized关键字,在调用方法时加锁;但是这个方式在锁住之后其他线程会阻塞,这会又很大的性能问题,于是考虑到分布式锁来解决这一问题

分布式锁

控制分布式系统有序的去对共享资源进行操作,通过互斥来保持一致性(synchronized关键字只在当前Java系统中作用);常用的分布式锁解决方案有三种:

  1. 基于数据库层面实现分布式锁(悲观锁,乐观锁)
  2. 基于缓存层面(如redis)实现分布式锁
  3. 基于zookeeper实现分布式锁

redis分布式锁解决方案

  • 设置一个公共锁:setnx lock-key value,利用setnx命令的返回值特征,有值则返返回设置失败,对该数据不具有控制权;无值则返回设置成功,可以进行下一步操作,每一个请求来操作都要先拿锁,拿不到锁就不能对数据操作锁需要设置有效时长,以免死锁,但锁的有效期可能低于程序的运行时间,所以需要看门狗对时间进行延续,redisson就帮助我们完成了这一工作,看门狗默认延期为30s超出默认时间看门狗也不会再延时
  • 释放公共锁:del lock-key

Redisson实现(集群环境)

  1. 导入依赖redisson-springboot-redisson-starter
  2. 配置文件:
  redis:
    cluster:
      nodes: 192.168.206.128:6379,192.168.206.128:6380,192.168.206.128:6381
      max-redirects: 3
    database: 0
    connect-timeout: 5000
    password: curry
    lettuce:
      pool:
        max-active: 1500
        max-wait: 5000
        max-idle: 500
        min-idle: 100
        shutdown-timeout: 1000
  1. 配置Bean
@Configuration
public class RedissonConfig {

    @Value("${spring.redis.cluster.nodes}")
    private List<String> urls;
    @Value("${spring.redis.password}")
    private String password;

    @Bean
    public RedissonClient redissonClient() throws IOException {

        for (int i = 0; i < urls.size(); i++) {
            urls.set(i,"redis://"+urls.get(i));
        }
        RedissonClient redisson;
        Config config = new Config();
        config.useClusterServers()
                .setScanInterval(2000)
                .setPassword(password)
                .setNodeAddresses(urls);
        redisson = Redisson.create(config);

        return redisson;
    }
}
  1. 获取与释放
    /**
     * 获取锁
     * @param redissonClient 客户端对象
     * @param key 锁的key
     * @return 如果当前没有这个锁则返回true,否则返回false
     */
    public static boolean getLock(RedissonClient redissonClient,String key){
        RLock rLock = redissonClient.getLock(key);
        return rLock.tryLock();
    }

    /**
     * 释放锁
     * @param redissonClient 客户端对象
     * @param key 锁的key
     */
    public static void unLock(RedissonClient redissonClient,String key){
        RLock rLock = redissonClient.getLock(key);
        rLock.unlock();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值