• SpringBoot集成redisson分布式锁


    原文:https://www.cnblogs.com/yangzhilong/p/7605807.html

    官方文档:https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95

    20180226更新:增加tryLock方法,建议后面去掉DistributedLocker接口和其实现类,直接在RedissLockUtil中注入RedissonClient实现类(简单但会丢失接口带来的灵活性)。

    1、引用redisson的pom

    <dependency>
        <groupId>org.redisson</groupId>
        <artifactId>redisson</artifactId>
        <version>3.5.0</version>
    </dependency>

    2、定义Lock的接口定义类

    复制代码
    import java.util.concurrent.TimeUnit;
    
    import org.redisson.api.RLock;
    
    public interface DistributedLocker {
    
        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);
    }
    复制代码

    3、Lock接口实现类

    复制代码
    import org.redisson.api.RLock;
    import org.redisson.api.RedissonClient;
    
    import java.util.concurrent.TimeUnit;
    
    public class RedissonDistributedLocker implements DistributedLocker {
        
        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;
        }
    }
    复制代码

    4、redisson属性装配类

    复制代码
    import org.springframework.boot.context.properties.ConfigurationProperties;
    
    @ConfigurationProperties(prefix = "redisson")
    public class RedissonProperties {
    
        private int timeout = 3000;
    
        private String address;
    
        private String password;
    
        private int connectionPoolSize = 64;
        
        private int connectionMinimumIdleSize=10;
    
        private int slaveConnectionPoolSize = 250;
    
        private int masterConnectionPoolSize = 250;
    
        private String[] sentinelAddresses;
    
        private String masterName;
    
        public int getTimeout() {
            return timeout;
        }
    
        public void setTimeout(int timeout) {
            this.timeout = timeout;
        }
    
        public int getSlaveConnectionPoolSize() {
            return slaveConnectionPoolSize;
        }
    
        public void setSlaveConnectionPoolSize(int slaveConnectionPoolSize) {
            this.slaveConnectionPoolSize = slaveConnectionPoolSize;
        }
    
        public int getMasterConnectionPoolSize() {
            return masterConnectionPoolSize;
        }
    
        public void setMasterConnectionPoolSize(int masterConnectionPoolSize) {
            this.masterConnectionPoolSize = masterConnectionPoolSize;
        }
    
        public String[] getSentinelAddresses() {
            return sentinelAddresses;
        }
    
        public void setSentinelAddresses(String sentinelAddresses) {
            this.sentinelAddresses = sentinelAddresses.split(",");
        }
    
        public String getMasterName() {
            return masterName;
        }
    
        public void setMasterName(String masterName) {
            this.masterName = masterName;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
        public int getConnectionPoolSize() {
            return connectionPoolSize;
        }
    
        public void setConnectionPoolSize(int connectionPoolSize) {
            this.connectionPoolSize = connectionPoolSize;
        }
    
        public int getConnectionMinimumIdleSize() {
            return connectionMinimumIdleSize;
        }
    
        public void setConnectionMinimumIdleSize(int connectionMinimumIdleSize) {
            this.connectionMinimumIdleSize = connectionMinimumIdleSize;
        }
    }
    复制代码

    5、SpringBoot自动装配类

    复制代码
    import org.apache.commons.lang3.StringUtils;
    import org.redisson.Redisson;
    import org.redisson.api.RedissonClient;
    import org.redisson.config.Config;
    import org.redisson.config.SentinelServersConfig;
    import org.redisson.config.SingleServerConfig;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import com.longge.lock.DistributedLocker;
    import com.longge.lock.RedissonDistributedLocker;
    import com.longge.lock.RedissonProperties;
    import com.longge.utils.RedissLockUtil;
    
    @Configuration
    @ConditionalOnClass(Config.class)
    @EnableConfigurationProperties(RedissonProperties.class)
    public class RedissonAutoConfiguration {
    
        @Autowired
        private RedissonProperties redssionProperties;
    
        /**
         * 哨兵模式自动装配
         * @return
         */
        @Bean
        @ConditionalOnProperty(name="redisson.master-name")
        RedissonClient redissonSentinel() {
            Config config = new Config();
            SentinelServersConfig serverConfig = config.useSentinelServers().addSentinelAddress(redssionProperties.getSentinelAddresses())
                    .setMasterName(redssionProperties.getMasterName())
                    .setTimeout(redssionProperties.getTimeout())
                    .setMasterConnectionPoolSize(redssionProperties.getMasterConnectionPoolSize())
                    .setSlaveConnectionPoolSize(redssionProperties.getSlaveConnectionPoolSize());
            
            if(StringUtils.isNotBlank(redssionProperties.getPassword())) {
                serverConfig.setPassword(redssionProperties.getPassword());
            }
            return Redisson.create(config);
        }
    
        /**
         * 单机模式自动装配
         * @return
         */
        @Bean
        @ConditionalOnProperty(name="redisson.address")
        RedissonClient redissonSingle() {
            Config config = new Config();
            SingleServerConfig serverConfig = config.useSingleServer()
                    .setAddress(redssionProperties.getAddress())
                    .setTimeout(redssionProperties.getTimeout())
                    .setConnectionPoolSize(redssionProperties.getConnectionPoolSize())
                    .setConnectionMinimumIdleSize(redssionProperties.getConnectionMinimumIdleSize());
            
            if(StringUtils.isNotBlank(redssionProperties.getPassword())) {
                serverConfig.setPassword(redssionProperties.getPassword());
            }
    
            return Redisson.create(config);
        }
    
        /**
         * 装配locker类,并将实例注入到RedissLockUtil中
         * @return
         */
        @Bean
        DistributedLocker distributedLocker(RedissonClient redissonClient) {
            DistributedLocker locker = new RedissonDistributedLocker();
            locker.setRedissonClient(redissonClient);
            RedissLockUtil.setLocker(locker);
            return locker;
        }
    
    }
    复制代码

    6、Lock帮助类

    复制代码
    import java.util.concurrent.TimeUnit;
    
    import org.redisson.api.RLock;
    
    import DistributedLocker;
    
    /**
     * redis分布式锁帮助类
     * @author yangzhilong
     *
     */
    public class RedissLockUtil {
        private static DistributedLocker redissLock;
        
        public static void setLocker(DistributedLocker locker) {
            redissLock = locker;
        }
        
        /**
         * 加锁
         * @param lockKey
         * @return
         */
        public static RLock lock(String lockKey) {
            return redissLock.lock(lockKey);
        }
    
        /**
         * 释放锁
         * @param lockKey
         */
        public static void unlock(String lockKey) {
            redissLock.unlock(lockKey);
        }
        
        /**
         * 释放锁
         * @param lock
         */
        public static void unlock(RLock lock) {
            redissLock.unlock(lock);
        }
    
        /**
         * 带超时的锁
         * @param lockKey
         * @param timeout 超时时间   单位:秒
         */
        public static RLock lock(String lockKey, int timeout) {
            return redissLock.lock(lockKey, timeout);
        }
        
        /**
         * 带超时的锁
         * @param lockKey
         * @param unit 时间单位
         * @param timeout 超时时间
         */
        public static RLock lock(String lockKey, TimeUnit unit ,int timeout) {
            return redissLock.lock(lockKey, unit, timeout);
        }
        
        /**
         * 尝试获取锁
         * @param lockKey
         * @param waitTime 最多等待时间
         * @param leaseTime 上锁后自动释放锁时间
         * @return
         */
        public static boolean tryLock(String lockKey, int waitTime, int leaseTime) {
            return redissLock.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 redissLock.tryLock(lockKey, unit, waitTime, leaseTime);
        }
    }
    复制代码

    属性文件实例:

    1、单机模式

    # redisson lock
    redisson.address=redis://10.18.75.115:6379
    redisson.password=

    这里如果不加redis://前缀会报URI构建错误,

    Caused by: java.net.URISyntaxException: Illegal character in scheme name at index 0

    其次,在redis进行连接的时候如果不对密码进行空判断,会出现AUTH校验失败的情况。

    Caused by: org.redisson.client.RedisException: ERR Client sent AUTH, but no password is set. channel

    2、哨兵模式

    redisson.master-name=mymaster
    redisson.password=xxxx
    redisson.sentinel-addresses=10.47.91.83:26379,10.47.91.83:26380,10.47.91.83:26381

    更多的配置信息可以去官网查看

  • 相关阅读:
    ABAP TCode
    SAP 常用的事务代码
    SAP FI TCode
    Little Tutorials的一篇文章断言:UML(统一建模语言)正在死亡:
    SAP PP TCode
    [ZT]解密中国IT人十大职业现状
    User Exit Query
    SAP客户端多语言设置
    一个女CIO的诞生
    DIY防奸手册之 主流硬盘型号解惑篇
  • 原文地址:https://www.cnblogs.com/shihaiming/p/8535262.html
Copyright © 2020-2023  润新知