您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“SpringBoot整合redis客戶端超時怎么解決”,內容詳細,步驟清晰,細節處理妥當,希望這篇“SpringBoot整合redis客戶端超時怎么解決”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
在開發的時候,使用到Lettuce連接redis,一段時間后不操作,再去操作redis,會報連接超時錯誤,在其重連后又可使用。
原因是:Lettuce 自適應拓撲刷新(Adaptive updates)與定時拓撲刷新(Periodic updates) 是默認關閉的導致問題的出現
1、重寫連接工廠實例,更改其LettuceClientConfiguration 為開啟拓撲更新
@Configuration public class RedisConfig { @Autowired private RedisProperties redisProperties; //這是固定的模板 //自己定義了一個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連接工廠實現 * LettuceConnectionFactory實現了RedisConnectionFactory接口 * UVPV用Redis * * @return 返回LettuceConnectionFactory */ @Bean(destroyMethod = "destroy") //這里要注意的是,在構建LettuceConnectionFactory 時,如果不使用內置的destroyMethod,可能會導致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()); //我使用的是單機redis,集群使用上面注釋的代碼 Set<RedisNode> nodes = new HashSet<>(); nodes.add(new RedisNode(redisProperties.getHost(), redisProperties.getPort())); 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 包括線程池配置和安全項配置 * * @param genericObjectPoolConfig common-pool2線程池 * @return lettuceClientConfiguration */ private LettuceClientConfiguration getLettuceClientConfiguration(GenericObjectPoolConfig genericObjectPoolConfig) { /* ClusterTopologyRefreshOptions配置用于開啟自適應刷新和定時刷新。如自適應刷新不開啟,Redis集群變更時將會導致連接異常! */ ClusterTopologyRefreshOptions topologyRefreshOptions = 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_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監控中查看 //.clientName(appName + "_lettuce") .build(); } }
2、SpringBoot2.3.x后,可使用配置文件中開啟lettuce的拓撲刷新
lettuce: pool: max-active: 20 max-wait: -1ms max-idle: 10 min-idle: 2 cluster: 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: xxx host: 172.16.0.x port: 6579 timeout: 5000 jedis: 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客戶端超時怎么解決”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。