「项目实战」Redisson分布式锁实战

每日一问

灵魂拷问之☞学法律的同学毕业为什么叫律师不叫法师?
各位巨佬们把答案留在评论区吧

正题

目前已经根据Redis搭建不同的环境配置了不同的配置文件,基本没有问题
下面就开始吧

Maven依赖

<!-- redisson 用于分布式锁 -->
<dependency>
   <groupId>org.redisson</groupId>
   <artifactId>redisson</artifactId>
   <version>3.11.1</version>
</dependency>

配置文件实体类

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;

@ConfigurationProperties(prefix = "redisson")
@RefreshScope
@Data
public class RedissonProperties {
    
    
    /**
     * 超时时间
     */
    private int timeout = 10000;
    /**
     * 地址
     */
    private String address;
    /**
     * 密码
     */
    private String password;
    /**
     * 连接数
     */
    private int connectionPoolSize = 64;
    /**
     * 最小空闲连接数 缺省:10
     */
    private int connectionMinimumIdleSize = 10;
    /**
     * 集群slave连接数
     */
    private int slaveConnectionPoolSize = 250;
    /**
     * 集群master连接数
     */
    private int masterConnectionPoolSize = 250;
    /**
     * 集群模式的地址
     */
    private String[] sentinelAddresses;
    /**
     * 集群master
     */
    private String masterName;
}

自动装配配置类,DistributedLock和RedisLockUtil在下面千万别引入错了

@Configuration
@ConditionalOnClass(Config.class)
@EnableConfigurationProperties(RedissonProperties.class)
@Slf4j
public class RedissonAutoConfiguration {
    
    

    @Autowired
    private RedissonProperties redssionProperties;

    @Bean
    @Primary
    @RefreshScope
    public RedissonClient getRedissonClient() {
    
    
        if (StringUtils.isNotEmpty(redssionProperties.getAddress())) {
    
    
            return redissonSingle();
        }
        if (redssionProperties.getSentinelAddresses() != null && redssionProperties.getSentinelAddresses().length > 0) {
    
    
            return redissonSentinel();
        }
        return null;
    }

    /**
     * 哨兵模式自动装配
     *
     * @return
     */
    RedissonClient redissonSentinel() {
    
    
        Config config = new Config();
        String[] address = redssionProperties.getSentinelAddresses();
        log.info("redisson Sentinel, ip : {}", JSON.toJSONString(address));
        SentinelServersConfig serverConfig = config.useSentinelServers().addSentinelAddress(redssionProperties.getSentinelAddresses())
                .setMasterName(redssionProperties.getMasterName())
                .setTimeout(redssionProperties.getTimeout())
                .setMasterConnectionPoolSize(redssionProperties.getMasterConnectionPoolSize())
                .setSlaveConnectionPoolSize(redssionProperties.getSlaveConnectionPoolSize());

        if (StringUtils.isNotEmpty(redssionProperties.getPassword())) {
    
    
            serverConfig.setPassword(redssionProperties.getPassword());
        }
        return Redisson.create(config);
    }

    /**
     * 单机模式自动装配
     *
     * @return
     */
    RedissonClient redissonSingle() {
    
    
        Config config = new Config();
        SingleServerConfig serverConfig = config.useSingleServer()
                .setAddress(redssionProperties.getAddress())
                .setTimeout(redssionProperties.getTimeout())
                .setConnectionPoolSize(redssionProperties.getConnectionPoolSize())
                .setConnectionMinimumIdleSize(redssionProperties.getConnectionMinimumIdleSize());
        log.info("redisson Single, ip : {}", serverConfig.getAddress());
        if (StringUtils.isNotEmpty(redssionProperties.getPassword())) {
    
    
            serverConfig.setPassword(redssionProperties.getPassword());
        }
        return Redisson.create(config);
    }

    /**
     * 装配locker类,并将实例注入到RedissLockUtil中
     *
     * @return
     */
    @Bean
    DistributedLock distributedLocker() {
    
    
        DistributedLock locker = new RedisLock();
        locker.setRedissonClient(getRedissonClient());
        RedisLockUtil.setLocker(locker);
        return locker;
    }
}

DistributedLock 锁接口类

public interface DistributedLock {
    
    

    RLock lock(String lockKey);

    RLock lock(String lockKey, int timeout);

    RLock lock(String lockKey, TimeUnit unit, int timeout);

    boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime);

    void unlock(String lockKey);

    void unlock(RLock lock);

    void setRedissonClient(RedissonClient redissonClient);
}

RedisLock redis锁实现类,DistributedLock 是上面这个类。

public class RedisLock implements DistributedLock {
    
    

    private RedissonClient redissonClient;

    @Override
    public RLock lock(String lockKey) {
    
    
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock();
        return lock;
    }

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

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

    @Override
    public boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) {
    
    
        RLock lock = redissonClient.getLock(lockKey);
        try {
    
    
            return lock.tryLock(waitTime, leaseTime, unit);
        } catch (InterruptedException e) {
    
    
            return false;
        }
    }

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

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

    public void setRedissonClient(RedissonClient redissonClient) {
    
    
        this.redissonClient = redissonClient;
    }
}

锁工具类

public final class RedisLockUtil {
    
    

    private static DistributedLock redisLock;

    public static void setLocker(DistributedLock locker) {
    
    
        redisLock = locker;
    }

    /**
     * 加锁
     *
     * @param lockKey
     * @return
     */
    public static RLock lock(String lockKey) {
    
    
        return redisLock.lock(lockKey);
    }

    /**
     * 释放锁
     *
     * @param lockKey
     */
    public static void unlock(String lockKey) {
    
    
        redisLock.unlock(lockKey);
    }

    /**
     * 释放锁
     *
     * @param lock
     */
    public static void unlock(RLock lock) {
    
    
        redisLock.unlock(lock);
    }

    /**
     * 带超时的锁
     *
     * @param lockKey
     * @param timeout 超时时间   单位:秒
     */
    public static RLock lock(String lockKey, int timeout) {
    
    
        return redisLock.lock(lockKey, timeout);
    }

    /**
     * 带超时的锁
     *
     * @param lockKey
     * @param unit    时间单位
     * @param timeout 超时时间
     */
    public static RLock lock(String lockKey, TimeUnit unit, int timeout) {
    
    
        return redisLock.lock(lockKey, unit, timeout);
    }

    /**
     * 尝试获取锁
     *
     * @param lockKey
     * @param waitTime  最多等待时间  单位(s)
     * @param leaseTime 上锁后自动释放锁时间 单位(s)
     * @return
     */
    public static boolean tryLock(String lockKey, int waitTime, int leaseTime) {
    
    
        return redisLock.tryLock(lockKey, TimeUnit.SECONDS, waitTime, leaseTime);
    }

    /**
     * 尝试获取锁
     *
     * @param lockKey
     * @param unit      时间单位
     * @param waitTime  最多等待时间
     * @param leaseTime 上锁后自动释放锁时间
     * @return
     */
    public static boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) {
    
    
        return redisLock.tryLock(lockKey, unit, waitTime, leaseTime);
    }
}

单元测试类

@SpringBootTest
@RunWith(SpringRunner.class)
@Slf4j
public class RedissonTest {
    
    

    @Test
    public void test() throws Exception {
    
    
        /**
         * 第一种
         */
        RedisLockUtil.lock("myLock");
        log.info("耗子尾汁redis");
        RedisLockUtil.unlock("myLock");
        /**
         * 第二种可以根据获取锁结果等待或者执行其他的业务流程
         */
        if (RedisLockUtil.tryLock("myLock", 1, 1000)) {
    
    
            log.info("redis 讲武德呀");
        }
        throw new Exception("不讲武德");
    }
}

本期到这里啦,写的不对的地方巨佬们多多指点,喜欢的话来一个一键三连吧

猜你喜欢

转载自blog.csdn.net/qq_34090008/article/details/110391758