欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

Springboot与Redisson整合教程:轻松实现分布式锁之七

最编程 2024-07-28 17:59:25
...

前言



该篇是基于springboot 项目整合 Redisson 实现对redis的操作。


内容:


1.以自定注解aop方式实现对接口使用分布式锁


2.使用RedissonClient对一些集合的常规操作,数据查询,存储等


正文



第一步:


pom.xml 添加核心依赖包:


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!--使用Redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.9.1</version>
        </dependency>


第二步:


新建RedissonConfig.java:


import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
 
/**
 * redisson bean管理
 */
@Configuration
public class RedissonConfig {
    
    /**
     * Redisson客户端注册
     * 单机模式
     */
    @Bean(destroyMethod = "shutdown")
    public RedissonClient createRedissonClient() throws IOException {
 
//       Config config = new Config();
//        SingleServerConfig singleServerConfig = config.useSingleServer();
//        singleServerConfig.setAddress("redis://127.0.0.1:6379");
//        singleServerConfig.setPassword("12345");
//        singleServerConfig.setTimeout(3000);
//        return Redisson.create(config)
 
        // 本例子使用的是yaml格式的配置文件,读取使用Config.fromYAML,如果是Json文件,则使用Config.fromJSON
        Config config = Config.fromYAML(RedissonConfig.class.getClassLoader().getResource("redisson-config.yml"));
        return Redisson.create(config);
    }
 
 
    /**
     * 主从模式 哨兵模式
     *
     **/
   /* @Bean
    public RedissonClient getRedisson() {
        RedissonClient redisson;
        Config config = new Config();
        config.useMasterSlaveServers()
                //可以用"rediss://"来启用SSL连接
                .setMasterAddress("redis://***(主服务器IP):6379").setPassword("web2017")
                .addSlaveAddress("redis://***(从服务器IP):6379")
                .setReconnectionTimeout(10000)
                .setRetryInterval(5000)
                .setTimeout(10000)
                .setConnectTimeout(10000);//(连接超时,单位:毫秒 默认值:3000);
        //  哨兵模式config.useSentinelServers().setMasterName("mymaster").setPassword("web2017").addSentinelAddress("***(哨兵IP):26379", "***(哨兵IP):26379", "***(哨兵IP):26380");
        redisson = Redisson.create(config);
        return redisson;
    }*/
 
 
   
 
    
 
}


上面配置里可以使用传值方式去连接redis,也可以选择从配置文件获取参数,反正方式多样。


redisson-config.yml 文件(如果没有密码设置为null即可):


#Redisson配置
singleServerConfig:
  address: "redis://127.0.0.1:6379"
  password: 12345
  clientName: null
  database: 7 #选择使用哪个数据库0~15
  idleConnectionTimeout: 10000
  pingTimeout: 1000
  connectTimeout: 10000
  timeout: 3000
  retryAttempts: 3
  retryInterval: 1500
  reconnectionTimeout: 3000
  failedAttempts: 3
  subscriptionsPerConnection: 5
  subscriptionConnectionMinimumIdleSize: 1
  subscriptionConnectionPoolSize: 50
  connectionMinimumIdleSize: 32
  connectionPoolSize: 64
  dnsMonitoringInterval: 5000
  #dnsMonitoring: false
 
threads: 0
nettyThreads: 0
codec:
  class: "org.redisson.codec.JsonJacksonCodec"
transportMode: "NIO"


第三步:


使用锁,新建DistributeLocker.java :


import java.util.concurrent.TimeUnit;
 
/**
 * @Author : JCccc
 * @CreateTime : 2020/5/13
 * @Description :
 **/
public interface  DistributeLocker {
 
    /**
     * 加锁
     * @param lockKey key
     */
    void lock(String lockKey);
 
    /**
     * 释放锁
     *
     * @param lockKey key
     */
    void unlock(String lockKey);
 
    /**
     * 加锁锁,设置有效期
     *
     * @param lockKey key
     * @param timeout 有效时间,默认时间单位在实现类传入
     */
    void lock(String lockKey, int timeout);
 
    /**
     * 加锁,设置有效期并指定时间单位
     * @param lockKey key
     * @param timeout 有效时间
     * @param unit    时间单位
     */
    void lock(String lockKey, int timeout, TimeUnit unit);
 
    /**
     * 尝试获取锁,获取到则持有该锁返回true,未获取到立即返回false
     * @param lockKey
     * @return true-获取锁成功 false-获取锁失败
     */
    boolean tryLock(String lockKey);
 
    /**
     * 尝试获取锁,获取到则持有该锁leaseTime时间.
     * 若未获取到,在waitTime时间内一直尝试获取,超过waitTime还未获取到则返回false
     * @param lockKey   key
     * @param waitTime  尝试获取时间
     * @param leaseTime 锁持有时间
     * @param unit      时间单位
     * @return true-获取锁成功 false-获取锁失败
     */
    boolean tryLock(String lockKey, long waitTime, long leaseTime, TimeUnit unit)
            throws InterruptedException;
 
    /**
     * 锁是否被任意一个线程锁持有
     * @param lockKey
     * @return true-被锁 false-未被锁
     */
    boolean isLocked(String lockKey);
 
    //lock.isHeldByCurrentThread()的作用是查询当前线程是否保持此锁定
    boolean isHeldByCurrentThread(String lockKey);
 
 
}


再是新建这个锁接口的实现类 ,RedissonDistributeLocker.java :


import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import java.util.concurrent.TimeUnit;
 
/**
 * redisson实现分布式锁接口
 */
public class RedissonDistributeLocker implements DistributeLocker {
 
    private RedissonClient redissonClient;
 
    public RedissonDistributeLocker(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }
 
    @Override
    public void lock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock();
    }
 
    @Override
    public void unlock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.unlock();
    }
 
    @Override
    public void lock(String lockKey, int leaseTime) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock(leaseTime, TimeUnit.MILLISECONDS);
    }
 
    @Override
    public void lock(String lockKey, int timeout, TimeUnit unit) {
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock(timeout, unit);
    }
 
    @Override
    public boolean tryLock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        return lock.tryLock();
    }
 
    @Override
    public boolean tryLock(String lockKey, long waitTime, long leaseTime,
                           TimeUnit unit) throws InterruptedException {
        RLock lock = redissonClient.getLock(lockKey);
        return lock.tryLock(waitTime, leaseTime, unit);
    }
 
    @Override
    public boolean isLocked(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        return lock.isLocked();
    }
 
    @Override
    public boolean isHeldByCurrentThread(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        return lock.isHeldByCurrentThread();
    }
 
 
}


然后新建锁操作工具类,RedissonLockUtils.java :


上一篇: 【高并发】你知道吗?大家都在使用Redisson实现分布式锁了!!-写在前面

下一篇: 理解并实现:可重入锁(ReentrantLock)在多线程中的应用