SpringBoot整合redis客户端超时怎么解决
SpringBoot整合redis客户端超时怎么解决
本文小编为大家详细介绍“SpringBoot整合redis客户端超时怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“SpringBoot整合redis客户端超时怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
问题
在开发的时候,使用到Lettuce连接redis,一段时间后不操作,再去操作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客户端超时怎么解决”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注恰卡编程网行业资讯频道。
推荐阅读
-
vue动态添加删除输入框(springboot vue怎么让数据库显示出来)
springbootvue怎么让数据库显示出来?一般情况下是前端调阅后端接口,来获取到数据库的数据,后端哪里会把数据库的数据整理...
-
php如何让Swoole/Pool进程池实现Redis持久连接
php如何让Swoole/Pool进程池实现Redis持久连接本篇...
-
php操作redis大全记录
php连接redis测试˂?php$redis=newRedis();$redis-˃conne...
-
PHP经典高级工程师面试题
1.PHP如何实现不用自带的cookie函数为客户端下发cookie。对于分布式系统,如何来保存session值...
-
PHP操作Redis数据库
-
php利用redis防止商品超发来限制抢购,简单又实用
-
php如何实现秒杀功能?php+redis模拟简单抢购场景,快来看看吧
-
PHP高级工程师面试题
-
Laravel结合Redis发送邮箱验证码
-
使用redis缓存实现多服务器PHP sessions共享