RedissonDistributedLock(redis分布式锁工具类,笔记)

redisson分布式锁, 支持全局与局部锁

  • RedissonDistributedLock
    
    package com.llb.cloudyoung.tool.lock;
    
    import com.llb.cloudyoung.tool.redis.RedissonConfig;
    import com.llb.cloudyoung.tool.utils.DateUtil;
    import com.llb.cloudyoung.tool.utils.LogUtil;
    import org.redisson.api.RLock;
    import org.redisson.api.RedissonClient;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    
    import java.util.concurrent.TimeUnit;
    import java.util.function.Supplier;
    
    /**
     * Description: redisson分布式锁, 支持全局与局部锁
     */
    @Configuration
    public class RedissonDistributedLock {
          
          
    
        private static final Logger logger = LoggerFactory.getLogger(RedissonDistributedLock.class);
    
        @Autowired
        private RedissonConfig redissonConfig;
    
        /**
         * 锁等待时间
         */
        private int defaultLockWaitTime = 5;
    
        /**
         * 锁默认失效时间
         */
        private int defaultLockLeaseTime = 10;
    
        public RedissonClient getRedisson() {
          
          
            return redissonConfig.getRedissonInstance();
        }
    
        /**
         * 获取锁对象
         * @param name
         * @return
         */
        public RLock getLock(String name) {
          
          
            return getRedisson().getLock(name);
        }
    
        /**
         * Description: 加锁方法     
         * @param supplier      方法
         * @param key           锁Key
         * @param lockWaitTime  等待时间
         * @param lockLeaseTime 默认失效时间
         */
        public <T> T locked(Supplier<T> supplier, String key, int lockWaitTime, int lockLeaseTime) throws Exception {
          
          
            lockWaitTime = lockWaitTime <= 0 ? defaultLockWaitTime : lockWaitTime;
            lockLeaseTime = lockLeaseTime <= 0 ? defaultLockLeaseTime : lockLeaseTime;
    
            RedissonClient redisson = this.getRedisson();
            RLock lock = redisson.getLock(key);
            boolean locked = false;
            try {
          
          
                locked = lock.tryLock(lockWaitTime, lockLeaseTime, TimeUnit.SECONDS);
                if (!locked) {
          
          
                    LogUtil.info(logger, "分布式锁等待超时! 等待时长:{0},当前时间为:{1}", defaultLockWaitTime, DateUtil.getNow());
                    throw new RuntimeException("获取分布式锁失败");
                }
                return supplier.get();
            } catch (Exception e) {
          
          
                LogUtil.error(logger, e, "lock error  当前时间为:{0}", DateUtil.getNow());
                throw e;
            } finally {
          
          
                if (locked) {
          
          
                    lock.unlock();
                }
            }
        }
    
        /**
         * Description: 加锁方法     
         * @param supplier      方法
         * @param key           锁Key
         */
        public <T> T locked(Supplier<T> supplier, String key) throws Exception {
          
          
            return locked(supplier, key, defaultLockWaitTime, defaultLockLeaseTime);
        }
    }
     
    
  • RedissonConfig
    
    package com.llb.cloudyoung.tool.redis;
    
    import com.llb.cloudyoung.tool.enums.RedisArchModelEnum;
    import org.apache.commons.lang.StringUtils;
    import org.redisson.Redisson;
    import org.redisson.api.RedissonClient;
    import org.redisson.client.codec.Codec;
    import org.redisson.config.Config;
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Configuration;
    
    import javax.annotation.Resource;
    
    /**
     * @Description: redisson 配置
     * @Version1.0 2018/3/27 16:41 by 王广宇 ([email protected]) 创建
     */
    @Configuration
    public class RedissonConfig implements InitializingBean {
          
          
    
        private final Config config = new Config();
        private RedissonClient redisson;
    
        //common configure
        @Value("${spring.redis.model:sentinel}")
        private String model;
    
        @Resource
        private RedissonProperties redissonProperties;
    
        private int idleConnectionTimeout = 10000;//连接空闲超时,单位:毫秒
        private int connectTimeout = 10000;//连接超时,单位:毫秒
        private int connectionPoolSize = 128;//连接池大小
        //sentinel、 master-slave、 cluster common configure
        private int slaveConnectionMinimumIdleSize = 20;//从节点最小空闲连接数
        private int slaveConnectionPoolSize = 128;//从节点连接池大小
        private int masterConnectionMinimumIdleSize = 20;//主节点最小空闲连接数
        private int masterConnectionPoolSize = 128;//主节点连接池大小
        private int scanInterval = 100;//集群状态扫描间隔时间,单位是毫秒
    
        private Codec codec;
    
        public RedissonConfig() {
          
          
    
        }
    
        public RedissonConfig(RedissonProperties redissonProperties) {
          
          
            this.redissonProperties = redissonProperties;
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
          
          
            init();
        }
    
        public void init() {
          
          
            if (StringUtils.isBlank(model)) {
          
          
                throw new IllegalArgumentException("RedissonConfig init method params with:[model] can not be empty......!");
            }
            if (RedisArchModelEnum.SINGLE.getModel().equals(model)) {
          
          
                this.initSingleRedissonClient();
            } else if (RedisArchModelEnum.SENTINEL.getModel().equals(model)) {
          
          
                this.initSentinelRedissonClient();
            } else if (RedisArchModelEnum.CLUSTER.getModel().equals(model)) {
          
          
                this.initClusterRedissonClient();
            } else {
          
          
                throw new IllegalArgumentException("RedissonConfig init method params with:[model] invalid......");
            }
        }
    
        /**
         * Description: init single redisson client
         *
         * @Version1.0 2017年8月24日 上午10:32:39 by 代鹏([email protected])创建
         */
        private void initSingleRedissonClient() {
          
          
            if (StringUtils.isBlank(redissonProperties.getUrl())) {
          
          
                throw new IllegalArgumentException("redis install mode choice single, must be set singleNodes params......!");
            }
            config.setCodec(this.getCodec());
            config.useSingleServer()
                    .setPassword(StringUtils.isNotBlank(redissonProperties.getPassword()) ? redissonProperties.getPassword() : null)
                    .setAddress(redissonProperties.getUrl())
                    .setDatabase(redissonProperties.getDatabase())
                    .setIdleConnectionTimeout(idleConnectionTimeout)
                    .setConnectTimeout(connectTimeout)
                    .setConnectionPoolSize(connectionPoolSize);
            redisson = Redisson.create(config);
        }
    
        /**
         * Description: init sentinel redisson client
         *
         * @Version1.0 2017年8月24日 上午10:33:15 by 代鹏([email protected])创建
         */
        private void initSentinelRedissonClient() {
          
          
            if (null == redissonProperties.getSentinel()) {
          
          
                throw new IllegalArgumentException("redis install mode choice sentinel, must be set sentinelAddress params......!");
            }
            if (StringUtils.isBlank(redissonProperties.getSentinel().getMaster())) {
          
          
                throw new IllegalArgumentException("redis install mode choice sentinel, must be set masterName params......!");
            }
            config.setCodec(this.getCodec());
            config.useSentinelServers()
                    .setMasterName(redissonProperties.getSentinel().getMaster())
                    .setPassword(StringUtils.isNotBlank(redissonProperties.getPassword()) ? redissonProperties.getPassword() : null)
                    .setDatabase(redissonProperties.getDatabase())
                    .setSlaveConnectionMinimumIdleSize(slaveConnectionMinimumIdleSize)
                    .setSlaveConnectionPoolSize(slaveConnectionPoolSize)
                    .setMasterConnectionMinimumIdleSize(masterConnectionMinimumIdleSize)
                    .setMasterConnectionPoolSize(masterConnectionPoolSize)
                    .setIdleConnectionTimeout(idleConnectionTimeout)
                    .setConnectTimeout(connectTimeout)
                    .addSentinelAddress(redissonProperties.getSentinel().getNodes().toArray(new String[]{
          
          }));
            redisson = Redisson.create(config);
        }
    
        /**
         * Description: init cluster redisson client
         *
         * @Version1.0 2017年8月24日 上午10:33:30 by 代鹏([email protected])创建
         */
        private void initClusterRedissonClient() {
          
          
            if (null == redissonProperties.getCluster()) {
          
          
                throw new IllegalArgumentException("redis install mode choice cluster, must be set clusterNodes params......!");
            }
            config.setCodec(this.getCodec());
            config.useClusterServers()
                    .setScanInterval(scanInterval)
                    .addNodeAddress(redissonProperties.getCluster().getNodes().toArray(new String[]{
          
          }))
                    .setPassword(redissonProperties.getPassword())
                    .setSlaveConnectionMinimumIdleSize(slaveConnectionMinimumIdleSize)
                    .setSlaveConnectionPoolSize(slaveConnectionPoolSize)
                    .setMasterConnectionMinimumIdleSize(masterConnectionMinimumIdleSize)
                    .setMasterConnectionPoolSize(masterConnectionPoolSize)
                    .setIdleConnectionTimeout(idleConnectionTimeout)
                    .setConnectTimeout(connectTimeout);
            redisson = Redisson.create(config);
        }
    
        public RedissonClient getRedissonInstance() {
          
          
            return redisson;
        }
    
        public Codec getCodec() {
          
          
            return codec;
        }
    
        public RedissonConfig setCodec(Codec codec) {
          
          
            this.codec = codec;
            return this;
        }
    
        public String getModel() {
          
          
            return model;
        }
    
        public void setModel(String model) {
          
          
            this.model = model;
        }
    }
    
    
    
    • RedisArchModelEnum
    
    SINGLE("single", "SINGLE"),
    MASTERSLAVE("ms", "MASTER-SLAVE"),
    SENTINEL("sentinel", "SENTINEL"),
    CLUSTER("cluster", "CLUSTER");
    
    private String model;
    private String desc;
    

猜你喜欢

转载自blog.csdn.net/qq_38893133/article/details/108992317