關(guān)于SpringBoot整合redis使用Lettuce客戶端超時(shí)問題
問題起因
做畢設(shè)的時(shí)候,使用到Lettuce連接redis,一段時(shí)間后不操作,再去操作redis,會(huì)報(bào)連接超時(shí)錯(cuò)誤,在其重連后又可使用。
原因是:Lettuce 自適應(yīng)拓?fù)渌⑿拢ˋdaptive updates)與定時(shí)拓?fù)渌⑿拢≒eriodic updates) 是默認(rèn)關(guān)閉的導(dǎo)致問題的出現(xiàn)
解決的方案
1、重寫連接工廠實(shí)例,更改其LettuceClientConfiguration 為開啟拓?fù)涓?/p>
@Configuration public class RedisConfig { @Autowired private RedisProperties redisProperties; //這是固定的模板 //自己定義了一個(gè)RedisTemplate @Bean @SuppressWarnings("all") public RedisTemplate<String, Object> redisTemplate(@Qualifier("lettuceConnectionFactoryUvPv") RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); //Json序列化配置 Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class); ObjectMapper om = new ObjectMapper(); 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的序列化 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); //key采用String的序列化方式 template.setKeySerializer(stringRedisSerializer); //hash的key也采用String的序列化方式 template.setHashKeySerializer(stringRedisSerializer); //value序列化方式采用jackson template.setValueSerializer(jackson2JsonRedisSerializer); //hash的value序列化方式采用jackson template.setHashValueSerializer(jackson2JsonRedisSerializer); template.afterPropertiesSet(); return template; } /** * 為RedisTemplate配置Redis連接工廠實(shí)現(xiàn) * LettuceConnectionFactory實(shí)現(xiàn)了RedisConnectionFactory接口 * UVPV用Redis * * @return 返回LettuceConnectionFactory */ @Bean(destroyMethod = "destroy") //這里要注意的是,在構(gòu)建LettuceConnectionFactory 時(shí),如果不使用內(nèi)置的destroyMethod,可能會(huì)導(dǎo)致Redis連接早于其它Bean被銷毀 public LettuceConnectionFactory lettuceConnectionFactoryUvPv() throws Exception { List<String> clusterNodes = redisProperties.getCluster().getNodes(); Set<RedisNode> nodes = new HashSet<>(); clusterNodes.forEach(address -> nodes.add(new RedisNode(address.split(":")[0].trim(), Integer.parseInt(address.split(":")[1])))); RedisClusterConfiguration clusterConfiguration = new RedisClusterConfiguration(); clusterConfiguration.setClusterNodes(nodes); clusterConfiguration.setPassword(RedisPassword.of(redisProperties.getPassword())); clusterConfiguration.setMaxRedirects(redisProperties.getCluster().getMaxRedirects()); RedisStandaloneConfiguration redisStandaloneConfiguration=new RedisStandaloneConfiguration(); redisStandaloneConfiguration.setHostName(redisProperties.getHost()); redisStandaloneConfiguration.setPassword(redisProperties.getPassword()); redisStandaloneConfiguration.setDatabase(redisProperties.getDatabase()); redisStandaloneConfiguration.setPort(redisProperties.getPort()); GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig(); poolConfig.setMaxIdle(redisProperties.getLettuce().getPool().getMaxIdle()); poolConfig.setMinIdle(redisProperties.getLettuce().getPool().getMinIdle()); poolConfig.setMaxTotal(redisProperties.getLettuce().getPool().getMaxActive()); return new LettuceConnectionFactory(redisStandaloneConfiguration, getLettuceClientConfiguration(poolConfig)); } /** * 配置LettuceClientConfiguration 包括線程池配置和安全項(xiàng)配置 * * @param genericObjectPoolConfig common-pool2線程池 * @return lettuceClientConfiguration */ private LettuceClientConfiguration getLettuceClientConfiguration(GenericObjectPoolConfig genericObjectPoolConfig) { /* ClusterTopologyRefreshOptions配置用于開啟自適應(yīng)刷新和定時(shí)刷新。如自適應(yīng)刷新不開啟,Redis集群變更時(shí)將會(huì)導(dǎo)致連接異常! */ ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder() //開啟自適應(yīng)刷新 //.enableAdaptiveRefreshTrigger(ClusterTopologyRefreshOptions.RefreshTrigger.MOVED_REDIRECT, ClusterTopologyRefreshOptions.RefreshTrigger.PERSISTENT_RECONNECTS) //開啟所有自適應(yīng)刷新,MOVED,ASK,PERSISTENT都會(huì)觸發(fā) .enableAllAdaptiveRefreshTriggers() // 自適應(yīng)刷新超時(shí)時(shí)間(默認(rèn)30秒) .adaptiveRefreshTriggersTimeout(Duration.ofSeconds(25)) //默認(rèn)關(guān)閉開啟后時(shí)間為30秒 // 開周期刷新 .enablePeriodicRefresh(Duration.ofSeconds(20)) // 默認(rèn)關(guān)閉開啟后時(shí)間為60秒 ClusterTopologyRefreshOptions.DEFAULT_REFRESH_PERIOD 60 .enablePeriodicRefresh(Duration.ofSeconds(2)) = .enablePeriodicRefresh().refreshPeriod(Duration.ofSeconds(2)) .build(); return LettucePoolingClientConfiguration.builder() .poolConfig(genericObjectPoolConfig) .clientOptions(ClusterClientOptions.builder().topologyRefreshOptions(topologyRefreshOptions).build()) //將appID傳入連接,方便Redis監(jiān)控中查看 //.clientName(appName + "_lettuce") .build(); } }
2、SpringBoot2.3.x后,可使用配置文件中開啟lettuce的拓?fù)渌⑿?/p>
lettuce: pool: max-active: 20 max-wait: -1ms max-idle: 10 min-idle: 2 cluster: refresh: adaptive: true #20秒自動(dòng)刷新一次 period: 20
3、更改連接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: jedis: 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} #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}
到此這篇關(guān)于SpringBoot整合redis使用Lettuce客戶端超時(shí)問題的文章就介紹到這了,更多相關(guān)SpringBoot整合redis內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringCloud如何利用Feign訪問外部http請求
這篇文章主要介紹了SpringCloud如何利用Feign訪問外部http請求,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03java實(shí)現(xiàn)基于UDP協(xié)議的聊天小程序操作
UDP是與TCP相對應(yīng)的協(xié)議,UDP適用于一次只傳送少量數(shù)據(jù)、對可靠性要求不高的應(yīng)用環(huán)境。正因?yàn)閁DP協(xié)議沒有連接的過程,所以它的通信效率高;但也正因?yàn)槿绱?,它的可靠性不如TCP協(xié)議高,本文給大家介紹java實(shí)現(xiàn)基于UDP協(xié)議的聊天小程序操作,感興趣的朋友一起看看吧2021-10-10解決java連接虛擬機(jī)Hbase無反應(yīng)的問題
這篇文章主要介紹了解決java連接虛擬機(jī)Hbase無反應(yīng)的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06Java 實(shí)戰(zhàn)項(xiàng)目之倉庫管理系統(tǒng)的實(shí)現(xiàn)流程
讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+SSM+jsp+mysql+maven實(shí)現(xiàn)一個(gè)倉庫管理系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平2021-11-11