[JAVA] spring boot优雅集成redisson详解

1645 0
王子 2022-11-8 17:21:10 | 显示全部楼层 |阅读模式
目录

    集成及注意事项手动注入redisson配置
      具体yaml配置注解方式需要一个切面



集成及注意事项

上一篇文章大白话说了一下redisson的可重入、可续约、阻塞、时间轮、红锁、联锁、加锁逻辑和解锁逻辑,如果大家有兴趣先看上一篇,直通车
拔剑起蒿莱
redisson支持redis环境,单机、集群、哨兵、云等。
这里就讲一下集群模式需要注意的地方,redisson启动会检测master/slave节点是否正常,一般来说3分片3主3从是没有什么问题的,但是如果测试环境1分片1主1从或者3主都是启动不了的。
除了环境需要注意,还有注意兼容有无密码的情况。

手动注入redisson配置

一般情况下,生产环境都是有密码的。有密码的话,建议手动注入redisson配置,不用spring boot来帮你集成,因为可能spring boot识别不了密码。
  1. @Configuration
  2. public class RedissonConfiguration {
  3.     @Value("${spring.redis.cluster.nodes}")
  4.     private String node;
  5.     @Value("${spring.redis.password:}")
  6.     private String password;
  7.     @Bean
  8.     public RedissonClient redissoClient() {
  9.         Config config = new Config();
  10.         String[] nodes = node.split(",");
  11.         ClusterServersConfig clusterServersConfig = config.useClusterServers();
  12.         for (String nodeAddress : nodes) {
  13.             clusterServersConfig.addNodeAddress(prefixAddress(nodeAddress));
  14.         }
  15.         if (StringUtils.isNotBlank(password)) {
  16.             clusterServersConfig.setPassword(password);
  17.         }
  18.         return Redisson.create(config);
  19.     }
  20.     private String prefixAddress(String address) {
  21.         if (!StringUtils.isBlank(address) && !address.startsWith("redis")) {
  22.             return "redis://" + address;
  23.         }
  24.         return address;
  25.     }
  26. }
复制代码
上面可以根据自己实际情况调优一些配置。见官网
当然除了密码需要注意,还有一点就是是否有ssl,目前所在company是用的亚马逊云,会有ssl
spring boot 兼容 redis 可以在yaml配置里天际: Ssl:true,但对于redisson来说添加前缀就可以啦:
rediss:// + ip:端口或者域名

具体yaml配置
  1. spring:
  2.   redis:
  3.     cluster:
  4.       nodes: rediss://clustercfg.xxx
  5.     password: 'xxx'
  6.     timeout: 30000
  7.     Ssl: true
  8.     lettuce:
  9.       pool:
  10.         max-idle: 100
复制代码
愿君学长松 慎勿作桃李
既然注意点讲完了,那么在讲下怎么使用吧
利用锁的互斥策略,想知道有锁的那些策略,见上一篇文章。
一开始这样的
  1. @Scheduled(cron = "${xxx:0 0 */2 * * ?}")
  2. public void createProcess() {
  3.     RLock lock = redisson.getLock(key);
  4.     try {
  5.         if (lock.tryLock()) {
  6.            // 执行运行程序
  7.         } else {
  8.             log.info("createProcess 获取锁失败");
  9.         }
  10.     } catch (Exception e) {
  11.         log.error("xxx", e);
  12.     } finally {
  13.         // 是否有锁 && 是否当前线程
  14.         if (lock != null && lock.isLocked() && lock.isHeldByCurrentThread()) {
  15.             lock.unlock();
  16.         }
  17.     }
  18. }
复制代码
咋一看是没有什么问题的,但是本次重构的定时任务比较多,因此会涉及到很多try catch相同的代码。

注解方式

解决重复代码方式之一就是封装,在就是注解切面,想到注解方式更加灵活
于是
  1. /**
  2. * Redisson 同步锁
  3. */
  4. @Retention(RetentionPolicy.RUNTIME)
  5. @Target(ElementType.METHOD)
  6. public @interface RedissonSyncLock {
  7.     String pref();
  8.     /**
  9.      * 锁后缀,一般前缀根据业务来定,后缀是具体的场景
  10.      */
  11.     String keyEL();
  12.     /**
  13.      * 等待时长 【需要区分是互斥还是阻塞,互斥默认0就可以】
  14.      */
  15.     int waitSec() default 0;
  16. }
复制代码
需要一个切面
  1. @Slf4j
  2. @Aspect
  3. @Component
  4. @RequiredArgsConstructor
  5. public class RedissonSyncLockAspect {
  6.     private final Redisson redisson;
  7.     @Around(value = "@annotation(xxx.RedissonSyncLock)")
  8.     public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
  9.         MethodSignature signature = (MethodSignature) joinPoint.getSignature();
  10.         RedissonSyncLock redissonSyncLock = signature.getMethod().getAnnotation(RedissonSyncLock.class);
  11.         Object[] args = joinPoint.getArgs();
  12.         String key = SpelUtil.parseSpel(signature.getMethod(), args, redissonSyncLock.keyEL());
  13.         RLock lock = null;
  14.         try {
  15.             if (StringUtils.isNotBlank(key) && !StringUtils.equals(key, "null")
  16.                 lock = redisson.getLock(redissonSyncLock.pref().concat(key));
  17.                 if (lock.tryLock(redissonSyncLock.waitSec(), TimeUnit.SECONDS)) {
  18.                     return joinPoint.proceed();
  19.                 }
  20.             }
  21.             log.info("RedissonSyncLockAspect 上锁失败 {}", key);
  22.         } finally {
  23.             if (lock != null && lock.isLocked() && lock.isHeldByCurrentThread()) {
  24.                 lock.unlock();
  25.             }
  26.         }
  27.     }
  28. }
复制代码
使用方法:
  1. @RedissonSyncLock(pref = KeyConstant.xxx, keyEL = "#bean.accountNo")
  2. private void xxx(Bean bean){
  3.      // 程序执行
  4. }
复制代码
的确使用起来是比较方便的。
以上就是spring boot优雅集成redisson详解的详细内容,更多关于spring boot集成redisson的资料请关注中国红客联盟其它相关文章!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2025 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行