千家信息网

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

发表于:2024-11-30 作者:千家信息网编辑
千家信息网最后更新 2024年11月30日,本文小编为大家详细介绍"SpringBoot整合redis客户端超时怎么解决",内容详细,步骤清晰,细节处理妥当,希望这篇"SpringBoot整合redis客户端超时怎么解决"文章能帮助大家解决疑惑
千家信息网最后更新 2024年11月30日SpringBoot整合redis客户端超时怎么解决

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

问题

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

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

解决的方案

方法一:

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

@Configurationpublic class RedisConfig {      @Autowired    private RedisProperties redisProperties;     //这是固定的模板    //自己定义了一个RedisTemplate    @Bean    @SuppressWarnings("all")    public RedisTemplate redisTemplate(@Qualifier("lettuceConnectionFactoryUvPv") RedisConnectionFactory factory) {        RedisTemplate template = new RedisTemplate<>();        template.setConnectionFactory(factory);         //Json序列化配置        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(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 clusterNodes = redisProperties.getCluster().getNodes();//        Set 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 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连接

            org.springframework.boot            spring-boot-starter-data-redis                                                io.lettuce                    lettuce-core                                                                 redis.clients            jedis        

配置文件

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客户端超时怎么解决"文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注行业资讯频道。

0