springboot中 redisson实现分布式锁

redis可以实现分布式锁,redisson就是对redis分布式锁的一个成功实现成品,当然我们自己也可以用redis实现分布式锁,不过既然有轮子了,为啥还要造呢,哈哈哈,这里重属笔记。
捋一下redis实现分布式的一些理念信的东西吧
redis可以用setnx命令实现分布式锁,然后在设置过期时间(避免死锁,执行完业务finall里释放锁),不过由于这两条命令并不是原子操作,所以高并发下还会出现问题,还好redis高版本提供了set(key,1,30,NX)命令,相当于setnx命令和设置过期时间,这是一个原子操作,这种方式,如果30秒内任务没有执行完成,那么redis锁会过期,其他线程发现没锁也会进入代码,那么就会出现第一个线程执行完会把第二个线程上的锁给释放掉,这种情况处理方式:将线程id当做value,key为锁,释放锁时,从redis中get到锁,判断锁是否为当前线程所上,但是就算这样也会有多个线程执行同一段代码,(锁永久失效),还有处理方法是,守护线程延续时间。。。。。自己使用redis实现完美分布式锁还是蛮麻烦的,所以就用redisson吧,接下来就直接上代码吧

pom中添加依赖

 <dependency>
                <groupId>org.redisson</groupId>
                <artifactId>redisson-spring-boot-starter</artifactId>
                <version>3.9.1</version>
 </dependency>

配置RedissonClient 的bean,下面代码,根据不同配置文件,创建不同bean,
单机版,或者集群版

package com.annaru.common.config.redis;

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

import java.io.IOException;


@Configuration
public class RedissonConfig {

    @Value("${annaru.redisson.model}")
    private String redissonModel;

    /**
     * redisson客户端
     *
     * @return
     * @throws IOException
     */
    @Bean(destroyMethod = "shutdown")
    public RedissonClient redissonClient() throws IOException {
        Config config = null;

        if ("single".equals(redissonModel)) {
            config = Config.fromYAML(new ClassPathResource("redisson-single-config.yml").getInputStream());
        } else if ("cluster".equals(redissonModel)) {
            config = Config.fromYAML(new ClassPathResource("redisson-cluster-config.yml").getInputStream());
        }
        return Redisson.create(config);
    }

}

接口层

package com.annaru.common.config.redis;

import org.redisson.api.RLock;

import java.util.concurrent.TimeUnit;

/**
 * @Description redisson 分布式锁接口
 **/
public interface RedissonLocker {

    RLock lock(String lockKey);

    /**
     * @param lockKey
     * @param leaseTime 加锁时间,单位秒
     * @return
     */
    RLock lock(String lockKey, Long leaseTime);

    /**
     * @param lockKey
     * @param unit
     * @param timeout 加锁时间
     * @return
     */
    RLock lock(String lockKey, TimeUnit unit, Long timeout);

    /**
     * 测试锁,拿到lock就返回true,否则返回false
     * 时间限制,拿不到lock,就等一段时间,超时返回false
     *
     * @param lockKey
     * @param unit
     * @param waitTime
     * @param leaseTime
     * @return
     */
    boolean tryLock(String lockKey, TimeUnit unit, Long waitTime, Long leaseTime);

    /**
     * 解锁
     *
     * @param lockKey
     */
    void unlock(String lockKey);

    /**
     * 解锁
     *
     * @param lock
     */
    void unlock(RLock lock);
}

实现类
业务代码中使用的话,只需要调用此类方法即可,

package com.annaru.common.config.redis;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @Description redisson 分布式锁接口实现类
 **/
@Component
public class RedissonLockerImpl implements RedissonLocker {

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 拿不到锁就不罢休,线程就一直lock
     *
     * @param lockKey
     * @return
     */
    @Override
    public RLock lock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock();
        return lock;
    }

    @Override
    public RLock lock(String lockKey, Long leaseTime) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock(leaseTime, TimeUnit.SECONDS);
        return lock;
    }

    @Override
    public RLock lock(String lockKey, TimeUnit unit, Long timeout) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock(timeout, unit);
        return lock;
    }

    @Override
    public boolean tryLock(String lockKey, TimeUnit unit, Long waitTime, Long leaseTime) {

        RLock lock = redissonClient.getLock(lockKey);
        try {
            return lock.tryLock(waitTime, leaseTime, unit);
        } catch (InterruptedException e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public void unlock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.unlock();

    }

    @Override
    public void unlock(RLock lock) {
        lock.lock();
    }
}

配置文件

##Redisson 单节点模式配置
singleServerConfig:
  idleConnectionTimeout: 10000
  pingTimeout: 1000
  connectTimeout: 10000
  timeout: 3000
  retryAttempts: 3
  retryInterval: 1500
  reconnectionTimeout: 3000
  failedAttempts: 3
  password: null
  subscriptionsPerConnection: 5
  clientName: null
  address: "redis://115.159.9*.*75:6379"
#  address: "redis://localhost:6379"
  subscriptionConnectionMinimumIdleSize: 1
  subscriptionConnectionPoolSize: 50
  connectionMinimumIdleSize: 32
  connectionPoolSize: 64
  database: 0
  #dnsMonitoring: false
  dnsMonitoringInterval: 5000
threads: 0
nettyThreads: 0
codec: !<org.redisson.codec.JsonJacksonCodec> {}
transportMode: "NIO"
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值