经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » Redis » 查看文章
关于SpringBoot整合redis使用Lettuce客户端超时问题
来源:jb51  时间:2021/8/4 13:35:25  对本文有异议

参考的博客

问题起因

做毕设的时候,使用到Lettuce连接redis,一段时间后不操作,再去操作redis,会报连接超时错误,在其重连后又可使用。

原因是:Lettuce 自适应拓扑刷新(Adaptive updates)与定时拓扑刷新(Periodic updates) 是默认关闭的导致问题的出现

解决的方案

1、重写连接工厂实例,更改其LettuceClientConfiguration 为开启拓扑更新

  1. @Configuration
  2. public class RedisConfig {
  3.  
  4.  
  5. @Autowired
  6. private RedisProperties redisProperties;
  7.  
  8. //这是固定的模板
  9. //自己定义了一个RedisTemplate
  10. @Bean
  11. @SuppressWarnings("all")
  12. public RedisTemplate<String, Object> redisTemplate(@Qualifier("lettuceConnectionFactoryUvPv") RedisConnectionFactory factory) {
  13. RedisTemplate<String, Object> template = new RedisTemplate<>();
  14. template.setConnectionFactory(factory);
  15.  
  16. //Json序列化配置
  17. Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
  18. ObjectMapper om = new ObjectMapper();
  19. om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
  20. om.activateDefaultTyping(om.getPolymorphicTypeValidator());
  21. om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
  22. //解决序列化问题
  23. om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
  24. jackson2JsonRedisSerializer.setObjectMapper(om);
  25.  
  26. //String的序列化
  27. StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
  28.  
  29. //key采用String的序列化方式
  30. template.setKeySerializer(stringRedisSerializer);
  31. //hash的key也采用String的序列化方式
  32. template.setHashKeySerializer(stringRedisSerializer);
  33.  
  34. //value序列化方式采用jackson
  35. template.setValueSerializer(jackson2JsonRedisSerializer);
  36.  
  37. //hash的value序列化方式采用jackson
  38. template.setHashValueSerializer(jackson2JsonRedisSerializer);
  39. template.afterPropertiesSet();
  40.  
  41. return template;
  42. }
  43.  
  44. /**
  45. * 为RedisTemplate配置Redis连接工厂实现
  46. * LettuceConnectionFactory实现了RedisConnectionFactory接口
  47. * UVPV用Redis
  48. *
  49. * @return 返回LettuceConnectionFactory
  50. */
  51. @Bean(destroyMethod = "destroy")
  52. //这里要注意的是,在构建LettuceConnectionFactory 时,如果不使用内置的destroyMethod,可能会导致Redis连接早于其它Bean被销毁
  53. public LettuceConnectionFactory lettuceConnectionFactoryUvPv() throws Exception {
  54.  
  55. List<String> clusterNodes = redisProperties.getCluster().getNodes();
  56. Set<RedisNode> nodes = new HashSet<>();
  57. clusterNodes.forEach(address -> nodes.add(new RedisNode(address.split(":")[0].trim(), Integer.parseInt(address.split(":")[1]))));
  58. RedisClusterConfiguration clusterConfiguration = new RedisClusterConfiguration();
  59. clusterConfiguration.setClusterNodes(nodes);
  60. clusterConfiguration.setPassword(RedisPassword.of(redisProperties.getPassword()));
  61. clusterConfiguration.setMaxRedirects(redisProperties.getCluster().getMaxRedirects());
  62.  
  63.  
  64. RedisStandaloneConfiguration redisStandaloneConfiguration=new RedisStandaloneConfiguration();
  65. redisStandaloneConfiguration.setHostName(redisProperties.getHost());
  66. redisStandaloneConfiguration.setPassword(redisProperties.getPassword());
  67. redisStandaloneConfiguration.setDatabase(redisProperties.getDatabase());
  68. redisStandaloneConfiguration.setPort(redisProperties.getPort());
  69.  
  70. GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
  71. poolConfig.setMaxIdle(redisProperties.getLettuce().getPool().getMaxIdle());
  72. poolConfig.setMinIdle(redisProperties.getLettuce().getPool().getMinIdle());
  73. poolConfig.setMaxTotal(redisProperties.getLettuce().getPool().getMaxActive());
  74.  
  75. return new LettuceConnectionFactory(redisStandaloneConfiguration, getLettuceClientConfiguration(poolConfig));
  76. }
  77.  
  78. /**
  79. * 配置LettuceClientConfiguration 包括线程池配置和安全项配置
  80. *
  81. * @param genericObjectPoolConfig common-pool2线程池
  82. * @return lettuceClientConfiguration
  83. */
  84. private LettuceClientConfiguration getLettuceClientConfiguration(GenericObjectPoolConfig genericObjectPoolConfig) {
  85. /*
  86. ClusterTopologyRefreshOptions配置用于开启自适应刷新和定时刷新。如自适应刷新不开启,Redis集群变更时将会导致连接异常!
  87. */
  88. ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
  89. //开启自适应刷新
  90. //.enableAdaptiveRefreshTrigger(ClusterTopologyRefreshOptions.RefreshTrigger.MOVED_REDIRECT, ClusterTopologyRefreshOptions.RefreshTrigger.PERSISTENT_RECONNECTS)
  91. //开启所有自适应刷新,MOVED,ASK,PERSISTENT都会触发
  92. .enableAllAdaptiveRefreshTriggers()
  93. // 自适应刷新超时时间(默认30秒)
  94. .adaptiveRefreshTriggersTimeout(Duration.ofSeconds(25)) //默认关闭开启后时间为30秒
  95. // 开周期刷新
  96. .enablePeriodicRefresh(Duration.ofSeconds(20)) // 默认关闭开启后时间为60秒 ClusterTopologyRefreshOptions.DEFAULT_REFRESH_PERIOD 60 .enablePeriodicRefresh(Duration.ofSeconds(2)) = .enablePeriodicRefresh().refreshPeriod(Duration.ofSeconds(2))
  97. .build();
  98. return LettucePoolingClientConfiguration.builder()
  99. .poolConfig(genericObjectPoolConfig)
  100. .clientOptions(ClusterClientOptions.builder().topologyRefreshOptions(topologyRefreshOptions).build())
  101. //将appID传入连接,方便Redis监控中查看
  102. //.clientName(appName + "_lettuce")
  103. .build();
  104. }
  105.  
  106. }

2、SpringBoot2.3.x后,可使用配置文件中开启lettuce的拓扑刷新

  1. lettuce:
  2. pool:
  3. max-active: 20
  4. max-wait: -1ms
  5. max-idle: 10
  6. min-idle: 2
  7. cluster:
  8. refresh:
  9. adaptive: true
  10. #20秒自动刷新一次
  11. period: 20

3、更改连接redis的连接方式,使用jedis连接

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-redis</artifactId>
  4. <exclusions>
  5. <exclusion>
  6. <groupId>io.lettuce</groupId>
  7. <artifactId>lettuce-core</artifactId>
  8. </exclusion>
  9. </exclusions>
  10. </dependency>
  11. <dependency>
  12. <groupId>redis.clients</groupId>
  13. <artifactId>jedis</artifactId>
  14. </dependency>
  1. spring:
  2. redis:
  3. jedis:
  4. pool:
  5. max-active: ${redis.config.maxTotal:1024}
  6. max-idle: ${redis.config.maxIdle:50}
  7. min-idle: ${redis.config.minIdle:1}
  8. max-wait: ${redis.config.maxWaitMillis:5000}
  9. #lettuce:
  10. #pool:
  11. #max-active: ${redis.config.maxTotal:1024}
  12. #max-idle: ${redis.config.maxIdle:50}
  13. #min-idle: ${redis.config.minIdle:1}
  14. #max-wait: ${redis.config.maxWaitMillis:5000}

到此这篇关于SpringBoot整合redis使用Lettuce客户端超时问题的文章就介绍到这了,更多相关SpringBoot整合redis内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号