当前位置:   article > 正文

springboot集成redisson的几种方式

springboot集成redisson

前言

本文主要描述springboot继承redisson的几种方式以及redisson分布式锁的使用;


一、redisson简介?

Redisson是架设在Redis基础上的一个Java驻内存数据网格(In-Memory Data Grid)。
Redisson在基于NIO的Netty框架上,充分的利用了Redis键值数据库提供的一系列优势,在Java实用工具包中常用接口的基础上,为使用者提供了一系列具有分布式特性的常用工具类。使得原本作为协调单机多线程并发程序的工具包获得了协调分布式多机多线程并发系统的能力,大大降低了设计和研发大规模分布式系统的难度。同时结合各富特色的分布式服务,更进一步简化了分布式环境中程序相互之间的协作。

最熟为人知的是它的分布式锁机制,它有比redis本身更多更强劲的功能

  1. 分布式锁原理 : 发送一段lua脚本(保证原子性)用以加锁,其本质是抢占key,谁先生成key谁就有锁
  2. 以后再补一篇原理

二、集成方式

redisson 集成springBoot并不是特别友好,因为它没有像redis这样写自动配置类,故不能仅写配置就能用

引入pom坐标:

  1. <!--分布式锁-->
  2. <dependency>
  3. <groupId>org.redisson</groupId>
  4. <artifactId>redisson</artifactId>
  5. <version>3.13.6</version>
  6. </dependency>

2.1自定义配置+手动注入

要点:

1.自己写配置属性

2.自己写@Bean注入redisson

配置类

  1. import com.xkj.ecommerce.utils.RedissonLockUtil;
  2. import lombok.Data;
  3. import org.redisson.Redisson;
  4. import org.redisson.api.RedissonClient;
  5. import org.redisson.config.Config;
  6. import org.redisson.config.SentinelServersConfig;
  7. import org.redisson.config.SingleServerConfig;
  8. import org.springframework.boot.autoconfigure.AutoConfigureOrder;
  9. import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
  10. import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  11. import org.springframework.boot.context.properties.ConfigurationProperties;
  12. import org.springframework.context.annotation.Bean;
  13. import org.springframework.context.annotation.Configuration;
  14. import java.util.Arrays;
  15. /**
  16. * @createDate 2021/1/18
  17. */
  18. @Configuration
  19. @ConfigurationProperties(prefix = "redisson")
  20. @Data
  21. @AutoConfigureOrder
  22. public class RedissonConfig {
  23. private int timeout = 3000;
  24. private String address;
  25. private String password;
  26. private int database = 0;
  27. private int connectionPoolSize = 64;
  28. private int connectionMinimumIdleSize = 10;
  29. private int slaveConnectionPoolSize = 250;
  30. private int masterConnectionPoolSize = 250;
  31. private String[] sentinelAddresses;
  32. private String masterName;
  33. public void setSentinelAddresses(String sentinelAddresses) {
  34. this.sentinelAddresses = Arrays.stream(sentinelAddresses.split(",")).map(s -> "redis://" + s).toArray(String[]::new);
  35. }
  36. public void setAddress(String address) {
  37. this.address = "redis://" + address;
  38. }
  39. /**
  40. * 哨兵模式自动装配
  41. */
  42. @Bean
  43. @ConditionalOnMissingBean(RedissonClient.class)
  44. @ConditionalOnProperty(name = "redisson.masterName")
  45. public RedissonLockUtil redissonSentinel() {
  46. Config config = new Config();
  47. SentinelServersConfig serverConfig = config.useSentinelServers().addSentinelAddress(this.getSentinelAddresses())
  48. .setMasterName(this.getMasterName())
  49. .setTimeout(this.getTimeout())
  50. .setMasterConnectionPoolSize(this.getMasterConnectionPoolSize())
  51. .setSlaveConnectionPoolSize(this.getSlaveConnectionPoolSize());
  52. if (StringUtils.isNotBlank(this.getPassword())) {
  53. serverConfig.setPassword(this.getPassword());
  54. }
  55. RedissonClient redissonClient = Redisson.create(config);
  56. RedissonLockUtil locker = new RedissonLockUtil();
  57. locker.setRedissonClient(redissonClient);
  58. return locker;
  59. }
  60. /**
  61. * 单机模式自动装配
  62. */
  63. @Bean
  64. @ConditionalOnProperty(name = "redisson.address")
  65. public RedissonLockUtil redissonSingle() {
  66. Config config = new Config();
  67. SingleServerConfig serverConfig = config.useSingleServer()
  68. .setAddress(this.getAddress())
  69. .setTimeout(this.getTimeout())
  70. .setConnectionPoolSize(this.getConnectionPoolSize())
  71. .setConnectionMinimumIdleSize(this.getConnectionMinimumIdleSize());
  72. if (StringUtils.isNotBlank(this.getPassword())) {
  73. serverConfig.setPassword(this.getPassword());
  74. }
  75. RedissonClient redissonClient = Redisson.create(config);
  76. RedissonLockUtil locker = new RedissonLockUtil();
  77. locker.setRedissonClient(redissonClient);
  78. return locker;
  79. }
  80. }

application.properties

  1. redisson.timeout=3000
  2. ....
  3. # 哨兵配置(用英文逗号隔开)
  4. # redisson.sentinelAddresses=192.168.2.100:3408,192.168.2.101:3408
  5. # 单机配置
  6. redisson.address=192.168.2.100:3408

2.2使用Yaml方式批量读取配置

要点:

1.使用redisson官方提供的工具类,读取指定配置项

配置类

  1. import org.redisson.Redisson;
  2. import org.redisson.api.RedissonClient;
  3. import org.redisson.config.Config;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. import java.io.IOException;
  7. @Configuration
  8. public class RedissonConfig {
  9. @Bean
  10. public RedissonClient redisson() throws IOException {
  11. // 本例子使用的是yaml格式的配置文件,读取使用Config.fromYAML,如果是Json文件,则使用Config.fromJSON
  12. Config config = Config.fromYAML(RedissonConfig.class.getClassLoader().getResource("redisson-config.yml"));
  13. return Redisson.create(config);
  14. }
  15. }

自行注入到工具类中,参考
RedissonClient redissonClient = Redisson.create(config);

RedissonLockUtil locker = new RedissonLockUtil(); locker.setRedissonClient(redissonClient);

redisson-config.yml

  1. #Redisson配置
  2. singleServerConfig:
  3. address: "redis://127.0.0.1:6379"
  4. password: null
  5. clientName: null
  6. database: 7 #选择使用哪个数据库0~15
  7. idleConnectionTimeout: 10000
  8. pingTimeout: 1000
  9. connectTimeout: 10000
  10. timeout: 3000
  11. retryAttempts: 3
  12. retryInterval: 1500
  13. reconnectionTimeout: 3000
  14. failedAttempts: 3
  15. subscriptionsPerConnection: 5
  16. subscriptionConnectionMinimumIdleSize: 1
  17. subscriptionConnectionPoolSize: 50
  18. connectionMinimumIdleSize: 32
  19. connectionPoolSize: 64
  20. dnsMonitoringInterval: 5000
  21. #dnsMonitoring: false
  22. threads: 0
  23. nettyThreads: 0
  24. codec:
  25. class: "org.redisson.codec.JsonJacksonCodec"
  26. transportMode: "NIO"

2.3使用spring boot自动配置

引入springboot-redisson坐标

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-redis</artifactId>
  4. </dependency>
  5. <!-- https://mvnrepository.com/artifact/org.redisson/redisson-spring-boot-starter -->
  6. <dependency>
  7. <groupId>org.redisson</groupId>
  8. <artifactId>redisson-spring-boot-starter</artifactId>
  9. <version>3.12.0</version>
  10. </dependency>

  与yaml方式类似,应该属于进阶版

application.yml

  1. # 公共的spring配置
  2. spring.redis.database=
  3. spring.redis.host=
  4. spring.redis.port=
  5. spring.redis.password=
  6. spring.redis.ssl=
  7. spring.redis.timeout=
  8. spring.redis.cluster.nodes=
  9. spring.redis.sentinel.master=
  10. spring.redis.sentinel.nodes=
  11. # Redisson 的特殊配置
  12. # 可以从本地的类路径下读取配置文件
  13. spring.redis.redisson.config=classpath:redisson-config.yml

  然后可以直接使用

  1. @Autowired
  2. RedissonClient redissonClient;

   三、工具类

  1. import org.redisson.api.RLock;
  2. import org.redisson.api.RedissonClient;
  3. import java.util.concurrent.TimeUnit;
  4. public class RedissonLockUtil {
  5. private static RedissonClient redissonClient;
  6. public void setRedissonClient(RedissonClient redissonCli) {
  7. redissonClient = redissonCli;
  8. }
  9. public static RLock lock(String lockKey) {
  10. RLock lock = redissonClient.getLock(lockKey);
  11. lock.lock();
  12. return lock;
  13. }
  14. public static RLock lock(String lockKey, int leaseTime) {
  15. RLock lock = redissonClient.getLock(lockKey);
  16. lock.lock(leaseTime, TimeUnit.SECONDS);
  17. return lock;
  18. }
  19. public static RLock lock(String lockKey, TimeUnit unit, int timeout) {
  20. RLock lock = redissonClient.getLock(lockKey);
  21. lock.lock(timeout, unit);
  22. return lock;
  23. }
  24. /**
  25. * 尝试获得锁,自定义 时间单位;等待时长;加锁时长
  26. */
  27. public static boolean tryLock(String lockKey, int waitTime, int leaseTime, TimeUnit unit) {
  28. RLock lock = redissonClient.getLock(lockKey);
  29. try {
  30. return lock.tryLock(waitTime, leaseTime, unit);
  31. } catch (InterruptedException e) {
  32. return false;
  33. }
  34. }
  35. /**
  36. * 尝试获得锁,自定义 等待时长;加锁时长 (默认为秒)
  37. */
  38. public static boolean tryLock(String lockKey, int waitTime, int leaseTime) {
  39. RLock lock = redissonClient.getLock(lockKey);
  40. try {
  41. return lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);
  42. } catch (InterruptedException e) {
  43. return false;
  44. }
  45. }
  46. /**
  47. * 尝试获得锁,自定义 等待时长 (加锁时长不限制;默认为秒)
  48. */
  49. public static boolean tryLock(String lockKey, int waitTime) {
  50. RLock lock = redissonClient.getLock(lockKey);
  51. try {
  52. return lock.tryLock(waitTime, TimeUnit.SECONDS);
  53. } catch (InterruptedException e) {
  54. return false;
  55. }
  56. }
  57. /**
  58. * 尝试获得锁,自定义 等待时长 (加锁时长不限制)
  59. */
  60. public static boolean tryLock(String lockKey, int waitTime, TimeUnit unit) {
  61. RLock lock = redissonClient.getLock(lockKey);
  62. try {
  63. return lock.tryLock(waitTime, unit);
  64. } catch (InterruptedException e) {
  65. return false;
  66. }
  67. }
  68. public static void unlock(String lockKey) {
  69. RLock lock = redissonClient.getLock(lockKey);
  70. lock.unlock();
  71. }
  72. public static void unlock(RLock lock) {
  73. lock.unlock();
  74. }
  75. }

 用的时候就可以直接 RedissonLockUtil.lock("test")


总结

(据说redisson和redisson-spring-boot-starter用的不是同一套体系,如果考虑引包的兼容性,建议用第三种方式)

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号