SpringBoot集成redisson分布式锁

  1. https://www.cnblogs.com/yangzhilong/p/7605807.html
  2.  
  3. 前几天同事刚让增加上这一块东西. 百度查一下 啥意思.. 学习一下.

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

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

20190711更新:redisson官方发布了redisson-spring-boot-starter,具体可以参考:https://github.com/redisson/redisson/tree/master/redisson-spring-boot-starter#spring-boot-starter

1、引用redisson的pom

  1. <dependency>
  2. <groupId>org.redisson</groupId>
  3. <artifactId>redisson</artifactId>
  4. <version>3.5.0</version>
  5. </dependency>

2、定义Lock的接口定义类

  1. import java.util.concurrent.TimeUnit;
  2.  
  3. import org.redisson.api.RLock;
  4.  
  5. public interface DistributedLocker {
  6.  
  7. RLock lock(String lockKey);
  8.  
  9. RLock lock(String lockKey, int timeout);
  10.  
  11. RLock lock(String lockKey, TimeUnit unit, int timeout);
  12.  
  13. boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime);
  14.  
  15. void unlock(String lockKey);
  16.  
  17. void unlock(RLock lock);
  18. }

3、Lock接口实现类

  1. import org.redisson.api.RLock;
  2. import org.redisson.api.RedissonClient;
  3.  
  4. import java.util.concurrent.TimeUnit;
  5.  
  6. public class RedissonDistributedLocker implements DistributedLocker {
  7.  
  8. private RedissonClient redissonClient;
  9.  
  10. @Override
  11. public RLock lock(String lockKey) {
  12. RLock lock = redissonClient.getLock(lockKey);
  13. lock.lock();
  14. return lock;
  15. }
  16.  
  17. @Override
  18. public RLock lock(String lockKey, int leaseTime) {
  19. RLock lock = redissonClient.getLock(lockKey);
  20. lock.lock(leaseTime, TimeUnit.SECONDS);
  21. return lock;
  22. }
  23.  
  24. @Override
  25. public RLock lock(String lockKey, TimeUnit unit ,int timeout) {
  26. RLock lock = redissonClient.getLock(lockKey);
  27. lock.lock(timeout, unit);
  28. return lock;
  29. }
  30.  
  31. @Override
  32. public boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) {
  33. RLock lock = redissonClient.getLock(lockKey);
  34. try {
  35. return lock.tryLock(waitTime, leaseTime, unit);
  36. } catch (InterruptedException e) {
  37. return false;
  38. }
  39. }
  40.  
  41. @Override
  42. public void unlock(String lockKey) {
  43. RLock lock = redissonClient.getLock(lockKey);
  44. lock.unlock();
  45. }
  46.  
  47. @Override
  48. public void unlock(RLock lock) {
  49. lock.unlock();
  50. }
  51.  
  52. public void setRedissonClient(RedissonClient redissonClient) {
  53. this.redissonClient = redissonClient;
  54. }
  55. }

4、redisson属性装配类

  1. import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  2. import org.springframework.boot.context.properties.ConfigurationProperties;
  3. import org.springframework.context.annotation.Configuration;
  4.  
  5. @Configuration
  6. @ConfigurationProperties(prefix = "redisson")
  7. @ConditionalOnProperty("redisson.password")
  8. public class RedissonProperties {
  9.  
  10. private int timeout = 3000;
  11.  
  12. private String address;
  13.  
  14. private String password;
  15.  
  16. private int database = 0;
  17.  
  18. private int connectionPoolSize = 64;
  19.  
  20. private int connectionMinimumIdleSize=10;
  21.  
  22. private int slaveConnectionPoolSize = 250;
  23.  
  24. private int masterConnectionPoolSize = 250;
  25.  
  26. private String[] sentinelAddresses;
  27.  
  28. private String masterName;
  29.  
  30. public int getTimeout() {
  31. return timeout;
  32. }
  33.  
  34. public void setTimeout(int timeout) {
  35. this.timeout = timeout;
  36. }
  37.  
  38. public int getSlaveConnectionPoolSize() {
  39. return slaveConnectionPoolSize;
  40. }
  41.  
  42. public void setSlaveConnectionPoolSize(int slaveConnectionPoolSize) {
  43. this.slaveConnectionPoolSize = slaveConnectionPoolSize;
  44. }
  45.  
  46. public int getMasterConnectionPoolSize() {
  47. return masterConnectionPoolSize;
  48. }
  49.  
  50. public void setMasterConnectionPoolSize(int masterConnectionPoolSize) {
  51. this.masterConnectionPoolSize = masterConnectionPoolSize;
  52. }
  53.  
  54. public String[] getSentinelAddresses() {
  55. return sentinelAddresses;
  56. }
  57.  
  58. public void setSentinelAddresses(String sentinelAddresses) {
  59. this.sentinelAddresses = sentinelAddresses.split(",");
  60. }
  61.  
  62. public String getMasterName() {
  63. return masterName;
  64. }
  65.  
  66. public void setMasterName(String masterName) {
  67. this.masterName = masterName;
  68. }
  69.  
  70. public String getPassword() {
  71. return password;
  72. }
  73.  
  74. public void setPassword(String password) {
  75. this.password = password;
  76. }
  77.  
  78. public String getAddress() {
  79. return address;
  80. }
  81.  
  82. public void setAddress(String address) {
  83. this.address = address;
  84. }
  85.  
  86. public int getConnectionPoolSize() {
  87. return connectionPoolSize;
  88. }
  89.  
  90. public void setConnectionPoolSize(int connectionPoolSize) {
  91. this.connectionPoolSize = connectionPoolSize;
  92. }
  93.  
  94. public int getConnectionMinimumIdleSize() {
  95. return connectionMinimumIdleSize;
  96. }
  97.  
  98. public void setConnectionMinimumIdleSize(int connectionMinimumIdleSize) {
  99. this.connectionMinimumIdleSize = connectionMinimumIdleSize;
  100. }
  101.  
  102. public int getDatabase() {
  103. return database;
  104. }
  105.  
  106. public void setDatabase(int database) {
  107. this.database = database;
  108. }
  109.  
  110. public void setSentinelAddresses(String[] sentinelAddresses) {
  111. this.sentinelAddresses = sentinelAddresses;
  112. }
  113. }
  1.  

5、SpringBoot自动装配类

  1. import org.apache.commons.lang3.StringUtils;
  2. import org.redisson.Redisson;
  3. import org.redisson.api.RedissonClient;
  4. import org.redisson.config.Config;
  5. import org.redisson.config.SentinelServersConfig;
  6. import org.redisson.config.SingleServerConfig;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
  9. import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  10. import org.springframework.boot.context.properties.EnableConfigurationProperties;
  11. import org.springframework.context.annotation.Bean;
  12. import org.springframework.context.annotation.Configuration;
  13.  
  14. import com.longge.lock.DistributedLocker;
  15. import com.longge.lock.RedissonDistributedLocker;
  16. import com.longge.lock.RedissonProperties;
  17. import com.longge.utils.RedissLockUtil;
  18.  
  19. @Configuration
  20. @ConditionalOnClass(Config.class)
  21. @EnableConfigurationProperties(RedissonProperties.class)
  22. public class RedissonAutoConfiguration {
  23.  
  24. @Autowired
  25. private RedissonProperties redssionProperties;
  26.  
  27. /**
  28. * 哨兵模式自动装配
  29. * @return
  30. */
  31. @Bean
  32. @ConditionalOnProperty(name="redisson.master-name")
  33. RedissonClient redissonSentinel() {
  34. Config config = new Config();
  35. SentinelServersConfig serverConfig = config.useSentinelServers().addSentinelAddress(redssionProperties.getSentinelAddresses())
  36. .setMasterName(redssionProperties.getMasterName())
  37. .setTimeout(redssionProperties.getTimeout())
  38. .setMasterConnectionPoolSize(redssionProperties.getMasterConnectionPoolSize())
  39. .setSlaveConnectionPoolSize(redssionProperties.getSlaveConnectionPoolSize());
  40.  
  41. if(StringUtils.isNotBlank(redssionProperties.getPassword())) {
  42. serverConfig.setPassword(redssionProperties.getPassword());
  43. }
  44. return Redisson.create(config);
  45. }
  46.  
  47. /**
  48. * 单机模式自动装配
  49. * @return
  50. */
  51. @Bean
  52. @ConditionalOnProperty(name="redisson.address")
  53. RedissonClient redissonSingle() {
  54. Config config = new Config();
  55. SingleServerConfig serverConfig = config.useSingleServer()
  56. .setAddress(redssionProperties.getAddress())
  57. .setTimeout(redssionProperties.getTimeout())
  58. .setConnectionPoolSize(redssionProperties.getConnectionPoolSize())
  59. .setConnectionMinimumIdleSize(redssionProperties.getConnectionMinimumIdleSize());
  60.  
  61. if(StringUtils.isNotBlank(redssionProperties.getPassword())) {
  62. serverConfig.setPassword(redssionProperties.getPassword());
  63. }
  64.  
  65. return Redisson.create(config);
  66. }
  67.  
  68. /**
  69. * 装配locker类,并将实例注入到RedissLockUtil中
  70. * @return
  71. */
  72. @Bean
  73. DistributedLocker distributedLocker(RedissonClient redissonClient) {
  74. DistributedLocker locker = new RedissonDistributedLocker();
  75. locker.setRedissonClient(redissonClient);
  76. RedissLockUtil.setLocker(locker);
  77. return locker;
  78. }
  79.  
  80. }

6、Lock帮助类

  1. import java.util.concurrent.TimeUnit;
  2.  
  3. import org.redisson.api.RLock;
  4.  
  5. import DistributedLocker;
  6.  
  7. /**
  8. * redis分布式锁帮助类
  9. * @author yangzhilong
  10. *
  11. */
  12. public class RedissLockUtil {
  13. private static DistributedLocker redissLock;
  14.  
  15. public static void setLocker(DistributedLocker locker) {
  16. redissLock = locker;
  17. }
  18.  
  19. /**
  20. * 加锁
  21. * @param lockKey
  22. * @return
  23. */
  24. public static RLock lock(String lockKey) {
  25. return redissLock.lock(lockKey);
  26. }
  27.  
  28. /**
  29. * 释放锁
  30. * @param lockKey
  31. */
  32. public static void unlock(String lockKey) {
  33. redissLock.unlock(lockKey);
  34. }
  35.  
  36. /**
  37. * 释放锁
  38. * @param lock
  39. */
  40. public static void unlock(RLock lock) {
  41. redissLock.unlock(lock);
  42. }
  43.  
  44. /**
  45. * 带超时的锁
  46. * @param lockKey
  47. * @param timeout 超时时间 单位:秒
  48. */
  49. public static RLock lock(String lockKey, int timeout) {
  50. return redissLock.lock(lockKey, timeout);
  51. }
  52.  
  53. /**
  54. * 带超时的锁
  55. * @param lockKey
  56. * @param unit 时间单位
  57. * @param timeout 超时时间
  58. */
  59. public static RLock lock(String lockKey, TimeUnit unit ,int timeout) {
  60. return redissLock.lock(lockKey, unit, timeout);
  61. }
  62.  
  63. /**
  64. * 尝试获取锁
  65. * @param lockKey
  66. * @param waitTime 最多等待时间
  67. * @param leaseTime 上锁后自动释放锁时间
  68. * @return
  69. */
  70. public static boolean tryLock(String lockKey, int waitTime, int leaseTime) {
  71. return redissLock.tryLock(lockKey, TimeUnit.SECONDS, waitTime, leaseTime);
  72. }
  73.  
  74. /**
  75. * 尝试获取锁
  76. * @param lockKey
  77. * @param unit 时间单位
  78. * @param waitTime 最多等待时间
  79. * @param leaseTime 上锁后自动释放锁时间
  80. * @return
  81. */
  82. public static boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) {
  83. return redissLock.tryLock(lockKey, unit, waitTime, leaseTime);
  84. }
  85. }

属性文件实例:

1、单机模式

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

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

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

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

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

2、哨兵模式

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

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

[转帖]SpringBoot集成redisson分布式锁的更多相关文章

  1. SpringBoot集成redisson分布式锁

    官方文档:https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95 20180226更新:增加tryLock方法,建议后面去掉Distr ...

  2. springboot整合redisson分布式锁

    一.通过maven引入redisson的jar包 <dependency> <groupId>org.redisson</groupId> <artifact ...

  3. SpringBoot集成Redis分布式锁以及Redis缓存

    https://blog.csdn.net/qq_26525215/article/details/79182687 集成Redis 首先在pom.xml中加入需要的redis依赖和缓存依赖 < ...

  4. Redisson分布式锁的简单使用

    一:前言 我在实际环境中遇到了这样一种问题,分布式生成id的问题!因为业务逻辑的问题,我有个生成id的方法,是根据业务标识+id当做唯一的值! 而uuid是递增生成的,从1开始一直递增,那么在同一台机 ...

  5. Redisson分布式锁实现

    转: Redisson分布式锁实现 2018年09月07日 15:30:32 校长我错了 阅读数:3303   转:分布式锁和Redisson实现 概述 分布式系统有一个著名的理论CAP,指在一个分布 ...

  6. Redisson 分布式锁实战与 watch dog 机制解读

    Redisson 分布式锁实战与 watch dog 机制解读 目录 Redisson 分布式锁实战与 watch dog 机制解读 背景 普通的 Redis 分布式锁的缺陷 Redisson 提供的 ...

  7. 又长又细,万字长文带你解读Redisson分布式锁的源码

    前言 上一篇文章写了Redis分布式锁的原理和缺陷,觉得有些不过瘾,只是简单的介绍了下Redisson这个框架,具体的原理什么的还没说过呢.趁年前项目忙的差不多了,反正闲着也是闲着,不如把Rediss ...

  8. Redisson 分布式锁实现之前置篇 → Redis 的发布/订阅 与 Lua

    开心一刻 我找了个女朋友,挺丑的那一种,她也知道自己丑,平常都不好意思和我一块出门 昨晚,我带她逛超市,听到有两个人在我们背后小声嘀咕:"看咱前面,想不到这么丑都有人要." 女朋友 ...

  9. Redisson 分布式锁源码 02:看门狗

    前言 说起 Redisson,比较耳熟能详的就是这个看门狗(Watchdog)机制. 本文就一起看看加锁成功之后的看门狗(Watchdog)是如何实现的? 加锁成功 在前一篇文章中介绍了可重入锁加锁的 ...

随机推荐

  1. KMP + BZOJ 4974 [Lydsy1708月赛]字符串大师

    KMP 重点:失配nxtnxtnxt数组 意义:nxt[i]nxt[i]nxt[i]表示在[0,i−1][0,i-1][0,i−1]内最长相同前后缀的长度 图示: 此时nxt[i]=jnxt[i]=j ...

  2. c# NPOI aspx导出数据

    public static class XSSFWorkbook_Excel { /// <summary> /// GetExcel /// </summary> /// & ...

  3. pyqt5 + pyinstaller 制作爬虫小程序

    环境:mac python3.7 pyqt5 pyinstaller ps: 主要是熟悉pyqt5, 加入了单选框 输入框 文本框 文件夹选择框及日历下拉框 效果图: pyqt5 主程序文件 # -* ...

  4. 自助法(Bootstraping)

    自助法(Bootstraping)是另一种模型验证(评估)的方法(之前已经介绍过单次验证和交叉验证:验证和交叉验证(Validation & Cross Validation)).其以自助采样 ...

  5. iphone中input按钮设置disabled属性出现灰色背景没有显示问题

    在项目中发现发送验证码的按钮,在点击后添加disabled属性后,iphone手机中出现disabled属性的默认背景颜色没有显示,反而直接显示它下面的父级元素的白色 点击前 点击后 倒计时的按钮消失 ...

  6. kafka 创建消费者报错

    kafka-console-consumer.sh --zookeeper master:2181,slave1:2181,slave2:2181 --topic test --from-beginn ...

  7. hhhhh臭不要脸//捂脸)多不好意思啊you进步惹

    如题↑↑↑ 千万不要相信题目 还是看图说话吧↓↓↓ 我真的蒟蒻啊,,,准确率在70边缘徘徊,卑微☹ 不过还是侥幸地进入了前 30 名! 今天七夕欸,然鹅,,, qq空间里面弥漫着恋爱的酸臭味 香气,‘ ...

  8. SDN阅读作业

    阅读文章<软件定义网络(SDN)研究进展>,并根据所阅读的文章,书写一篇博客,回答以下问题(至少3个): 1.为什么需要SDN?SDN特点? 随着网络规模的不断扩大,传统网络设备繁复的协议 ...

  9. js注册表单中实现地区选择效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. hdoj - 1506 直方图中最大的矩形

    Problem Description A histogram is a polygon composed of a sequence of rectangles aligned at a commo ...