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);@Autowiredprivate 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 王广宇 (wanggy@cloud-young.com) 创建*/
    @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;@Resourceprivate RedissonProperties redissonProperties;private int idleConnectionTimeout = 10000;//连接空闲超时,单位:毫秒private int connectTimeout = 10000;//连接超时,单位:毫秒private int connectionPoolSize = 128;//连接池大小//sentinel、 master-slave、 cluster common configureprivate 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;}@Overridepublic 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 代鹏(daipeng.456@gmail.com)创建*/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 代鹏(daipeng.456@gmail.com)创建*/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 代鹏(daipeng.456@gmail.com)创建*/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;
    

RedissonDistributedLock(redis分布式锁工具类,笔记)相关推荐

  1. redis分布式锁工具类

    import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.redis.core. ...

  2. java分布式锁工具类_java 通过redis实现分布式锁

    1. 开局 在多线程环境中,经常会碰到需要加锁的情况,由于现在的系统基本都是集群分布式部署,JVM的lock已经不能满足分布式要求,分布式锁就这样产生了... 百度一下,网上有很多分布式锁的方案或者例 ...

  3. Redis分布式锁的原理以及如何续期

    面试问题 Redis锁的过期时间小于业务的执行时间该如何续期? 问题分析 首先如果你之前用Redis的分布式锁的姿势正确,并且看过相应的官方文档的话,这个问题So easy.我们来看 很多同学在用分布 ...

  4. 面试官问我,Redis分布式锁如何续期?懵了。

    作者:肥朝,来自:肥朝(ID:feichao_java) 前言 上一篇[面试官问我,使用Dubbo有没有遇到一些坑?我笑了.]之后,又有一位粉丝和我说在面试过程中被虐了.鉴于这位粉丝是之前肥朝的老粉丝 ...

  5. 京东秒杀系统模块的Redis分布式锁深度剖析,没给你讲明白你打我

    1|0背景 目前开发过程中,按照公司规范,需要依赖框架中的缓存组件.不得不说,做组件的大牛对CRUD操作的封装,连接池.缓存路由.缓存安全性的管控都处理的无可挑剔.但是有一个小问题,该组件没有对分布式 ...

  6. redis desktop manager_面试官:Redis分布式锁如何解决锁超时问题?

    Java面试笔试面经.Java技术每天学习一点 Java面试 关注不迷路 作者:wangzaiplus 来源:https://www.jianshu.com/u/8cb4591440ca 一.前言 关 ...

  7. Redis分布式锁实战

    背景 目前开发过程中,按照公司规范,需要依赖框架中的缓存组件.不得不说,做组件的大牛对CRUD操作的封装,连接池.缓存路由.缓存安全性的管控都处理的无可挑剔.但是有一个小问题,该组件没有对分布式锁做实 ...

  8. redis续期_面试官:Redis分布式锁如何解决锁超时问题的?

    一.前言 关于redis分布式锁, 查了很多资料, 发现很多只是实现了最基础的功能, 但是, 并没有解决当锁已超时而业务逻辑还未执行完的问题, 这样会导致: A线程超时时间设为10s(为了解决死锁问题 ...

  9. 以商品超卖为例讲解Redis分布式锁

    本案例主要讲解Redis实现分布式锁的两种实现方式:Jedis实现.Redisson实现.网上关于这方面讲解太多了,小编自认为文笔没他们好,还是用示例代码说明. 一.jedis 实现 该方案只考虑Re ...

最新文章

  1. STL 去重 unique
  2. RabbitMQ—常见报错
  3. Mathematica开方语法
  4. 026 模块3-random库的使用
  5. 让Internet Explorer成为你的软件集成平台
  6. hud android,Android 加载等待控件 ZFProgressHUD
  7. 直接下载Google Play上APP的安装包
  8. 【原创】 互联网大事记-开章
  9. python程序设计 清华大学出版社 pdf下载-清华大学出版社-图书详情-《Python程序设计教程》...
  10. Java字符串拼接的优雅方式
  11. 关于工业相机的基本知识
  12. alk In Web Security(安全世界观): Devleping a Secure Wesite
  13. 还在搞三层架构?了解下 DDD 分层架构的三种模式吧 !
  14. jquery获取父元素下的第n个子元素
  15. OPenGL 学习笔记之 VAO VBO EBO 以及SHADER 并使用其绘制三角形
  16. 【CG】汇总开源的三维图形/计算几何/CAD算法库
  17. Docker构建基于阿里云epel源的CentOS7 epel源镜像
  18. 视频教程-支付宝生活缴费商业项目标准版-Java
  19. Android 9.0默认支持的语言
  20. tg测试软件,TG Pro——硬件温度检测工具

热门文章

  1. 本地门户 PHP,基于ThinkPHP框架开发的本地智慧生活门户O2O系统V3.9.9全新界面商业版+PC和WAP端多个功能+商家+物业+社区+街道办独立后台...
  2. cad在图层设置中改不了线性和线宽
  3. POI单元格样式、行高列宽、合并单元格设置
  4. 2021-07-11 远程连接电脑后,插入耳机听不到远程电脑上播放器的声音
  5. Numpy的dtype设置方法
  6. Android耳机拔插事件流程
  7. Linux 下使用 C++ 实现的 Web 文件服务器
  8. 《原神》多名女角色外观调整,不少玩家纷纷表示:心碎了
  9. 服务器系统日志关机重启,服务器关机重启日志
  10. android kill 命令杀死进程,【Android 应用开发】Android 杀进程总结 ( 杀后台进程 | 杀前台进程 | 杀其它进程 )...