SpringBoot整合redis客户端超时怎么解决

SpringBoot整合redis客户端超时怎么解决

本文小编为大家详细介绍“SpringBoot整合redis客户端超时怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“SpringBoot整合redis客户端超时怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

问题

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

SpringBoot整合redis客户端超时怎么解决

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

解决的方案

方法一:

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

@ConfigurationpublicclassRedisConfig{@AutowiredprivateRedisPropertiesredisProperties;//这是固定的模板//自己定义了一个RedisTemplate@Bean@SuppressWarnings("all")publicRedisTemplate<String,Object>redisTemplate(@Qualifier("lettuceConnectionFactoryUvPv")RedisConnectionFactoryfactory){RedisTemplate<String,Object>template=newRedisTemplate<>();template.setConnectionFactory(factory);//Json序列化配置Jackson2JsonRedisSerializer<Object>jackson2JsonRedisSerializer=newJackson2JsonRedisSerializer<Object>(Object.class);ObjectMapperom=newObjectMapper();om.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY);om.activateDefaultTyping(om.getPolymorphicTypeValidator());om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);//解决序列化问题om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);jackson2JsonRedisSerializer.setObjectMapper(om);//String的序列化StringRedisSerializerstringRedisSerializer=newStringRedisSerializer();//key采用String的序列化方式template.setKeySerializer(stringRedisSerializer);//hash的key也采用String的序列化方式template.setHashKeySerializer(stringRedisSerializer);//value序列化方式采用jacksontemplate.setValueSerializer(jackson2JsonRedisSerializer);//hash的value序列化方式采用jacksontemplate.setHashValueSerializer(jackson2JsonRedisSerializer);template.afterPropertiesSet();returntemplate;}/***为RedisTemplate配置Redis连接工厂实现*LettuceConnectionFactory实现了RedisConnectionFactory接口*UVPV用Redis**@return返回LettuceConnectionFactory*/@Bean(destroyMethod="destroy")//这里要注意的是,在构建LettuceConnectionFactory时,如果不使用内置的destroyMethod,可能会导致Redis连接早于其它Bean被销毁publicLettuceConnectionFactorylettuceConnectionFactoryUvPv()throwsException{//List<String>clusterNodes=redisProperties.getCluster().getNodes();//Set<RedisNode>nodes=newHashSet<>();//clusterNodes.forEach(address->nodes.add(newRedisNode(address.split(":")[0].trim(),Integer.parseInt(address.split(":")[1]))));//RedisClusterConfigurationclusterConfiguration=newRedisClusterConfiguration();//clusterConfiguration.setClusterNodes(nodes);//clusterConfiguration.setPassword(RedisPassword.of(redisProperties.getPassword()));//clusterConfiguration.setMaxRedirects(redisProperties.getCluster().getMaxRedirects());//我使用的是单机redis,集群使用上面注释的代码Set<RedisNode>nodes=newHashSet<>();nodes.add(newRedisNode(redisProperties.getHost(),redisProperties.getPort()));RedisStandaloneConfigurationredisStandaloneConfiguration=newRedisStandaloneConfiguration();redisStandaloneConfiguration.setHostName(redisProperties.getHost());redisStandaloneConfiguration.setPassword(redisProperties.getPassword());redisStandaloneConfiguration.setDatabase(redisProperties.getDatabase());redisStandaloneConfiguration.setPort(redisProperties.getPort());GenericObjectPoolConfigpoolConfig=newGenericObjectPoolConfig();poolConfig.setMaxIdle(redisProperties.getLettuce().getPool().getMaxIdle());poolConfig.setMinIdle(redisProperties.getLettuce().getPool().getMinIdle());poolConfig.setMaxTotal(redisProperties.getLettuce().getPool().getMaxActive());returnnewLettuceConnectionFactory(redisStandaloneConfiguration,getLettuceClientConfiguration(poolConfig));}/***配置LettuceClientConfiguration包括线程池配置和安全项配置**@paramgenericObjectPoolConfigcommon-pool2线程池*@returnlettuceClientConfiguration*/privateLettuceClientConfigurationgetLettuceClientConfiguration(GenericObjectPoolConfiggenericObjectPoolConfig){/*ClusterTopologyRefreshOptions配置用于开启自适应刷新和定时刷新。如自适应刷新不开启,Redis集群变更时将会导致连接异常!*/ClusterTopologyRefreshOptionstopologyRefreshOptions=ClusterTopologyRefreshOptions.builder()//开启自适应刷新//.enableAdaptiveRefreshTrigger(ClusterTopologyRefreshOptions.RefreshTrigger.MOVED_REDIRECT,ClusterTopologyRefreshOptions.RefreshTrigger.PERSISTENT_RECONNECTS)//开启所有自适应刷新,MOVED,ASK,PERSISTENT都会触发.enableAllAdaptiveRefreshTriggers()//自适应刷新超时时间(默认30秒).adaptiveRefreshTriggersTimeout(Duration.ofSeconds(25))//默认关闭开启后时间为30秒//开周期刷新.enablePeriodicRefresh(Duration.ofSeconds(20))//默认关闭开启后时间为60秒ClusterTopologyRefreshOptions.DEFAULT_REFRESH_PERIOD60.enablePeriodicRefresh(Duration.ofSeconds(2))=.enablePeriodicRefresh().refreshPeriod(Duration.ofSeconds(2)).build();returnLettucePoolingClientConfiguration.builder().poolConfig(genericObjectPoolConfig).clientOptions(ClusterClientOptions.builder().topologyRefreshOptions(topologyRefreshOptions).build())//将appID传入连接,方便Redis监控中查看//.clientName(appName+"_lettuce").build();}}

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

lettuce:pool:max-active:20max-wait:-1msmax-idle:10min-idle:2cluster:refresh:adaptive:true#20秒自动刷新一次period:20

方法二:

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

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><exclusions><exclusion><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId></exclusion></exclusions></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId></dependency>

配置文件

spring:redis:password:xxxhost:172.16.0.xport:6579timeout:5000jedis:pool:#最大连接数据库连接数,设0为没有限制max-active:8#最大等待连接中的数量,设0为没有限制max-idle:8#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。max-wait:-1ms#最小等待连接中的数量,设0为没有限制min-idle:0#lettuce:#pool:#max-active:${redis.config.maxTotal:1024}#max-idle:${redis.config.maxIdle:50}#min-idle:${redis.config.minIdle:1}#max-wait:${redis.config.maxWaitMillis:5000}

读到这里,这篇“SpringBoot整合redis客户端超时怎么解决”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注恰卡编程网行业资讯频道。

发布于 2022-03-29 22:27:38
收藏
分享
海报
0 条评论
37
上一篇:Springboot集成Redis实例分析 下一篇:怎么用SpringBoot实现秒杀系统
目录

    0 条评论

    本站已关闭游客评论,请登录或者注册后再评论吧~

    忘记密码?

    图形验证码