记一次线上环境 redis偶尔连接超时报错 解决
发布日期:2021-06-29 13:15:37 浏览次数:2 分类:技术文章

本文共 4259 字,大约阅读时间需要 14 分钟。

记一次线上环境 redis偶尔连接超时报错 解决

 

贴出本地控制台日志

 

 

 

说实话,很痛苦,跟进很久了,一直认为的jvm程序所使用的配置的连接池框架问题

因为程序为 springboot 2 spring 5 ;那么默认连接池为 lettuce

起初认为是原有的jedis 转换到 lettuce存在的各种bug问题,可能没配置好;

 

网上也寻找了相关的文章,发现大多数人的解决方案,就是在springboot的自动注入的配置文件中,配置不对,说spring.redis.timeout配置为0,导致不允许超时,那么就会抛出该异常;

所以只需要将其改为合理的范围即可,比如10s,那么本人也试过了,发现不顶用。

此处贴出配置文件(注:rediss不是写错,是故意不使用自动配置注入的):

然后就是连接池的问题了,本人尝试使用自定义注入连接池使用,不使用自动注入(此处怀疑是自动注入问题)结果也发现不行,

那么再怀疑是配置项不对,例如连接池的最小空闲链接、最大空闲链接数不合理,那么我本地在尝试调整的时候,本地模拟运行一段时间,发现还是会时不时抛出超时问题;

此处贴出本人的自定义注入配置文件(一个lettuce连接工厂)

/** * @description: LettuceConfiguration * @author: Wang Ji * @create: 2021/01/22 21:24 */@Slf4j@Configuration@AutoConfigureAfter(RedisAutoConfiguration.class)public class LettuceConfig {​    @Value("${spring.rediss.database}")    private int database = 0;​    @Value("${spring.rediss.host}")    private String host;​    @Value("${spring.rediss.port}")    private int port;​    @Value("${spring.rediss.password}")    private String password = null;​    @Value("${spring.rediss.timeout}")    private int timeout = 5000;​    @Value("${spring.rediss.lettuce.pool.max-idle}")    private int maxIdle = 8;​    @Value("${spring.rediss.lettuce.pool.min-idle}")    private int minIdle = 0;​    @Value("${spring.rediss.lettuce.pool.max-active}")    private int maxActive = 8;​    @Value("${spring.rediss.lettuce.pool.max-wait}")    private long maxWait;​    /**     * lettuce 连接工厂     *     * @param genericObjectPoolConfig     * @return     */    @Bean("redisConnectionFactory")    public RedisConnectionFactory redisConnectionFactory(@Qualifier("genericObjectPoolConfig") GenericObjectPoolConfig
genericObjectPoolConfig) {        // 单机版配置        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();        redisStandaloneConfiguration.setDatabase(database);        redisStandaloneConfiguration.setHostName(host);        redisStandaloneConfiguration.setPort(port);        redisStandaloneConfiguration.setPassword(RedisPassword.of(password));​        // 集群版配置//       RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();//       String[] serverArray = clusterNodes.split(",");//       Set
nodes = new HashSet
();//       for (String ipPort : serverArray) {//           String[] ipAndPort = ipPort.split(":");//           nodes.add(new RedisNode(ipAndPort[0].trim(), Integer.valueOf(ipAndPort[1])));//       }//       redisClusterConfiguration.setPassword(RedisPassword.of(password));//       redisClusterConfiguration.setClusterNodes(nodes);//       redisClusterConfiguration.setMaxRedirects(maxRedirects);​        LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()               .commandTimeout(Duration.ofMillis(timeout))               .poolConfig(genericObjectPoolConfig)               .build();        RedisConnectionFactory redisConnectionFactory = new LettuceConnectionFactory(redisStandaloneConfiguration, clientConfig);        if (ConnectionUtils.isLettuce(redisConnectionFactory)) {            log.warn("// RedisConnectionFactory is Lettuce");       } else if (ConnectionUtils.isJedis(redisConnectionFactory)) {            log.warn("// RedisConnectionFactory is Jedis");       }​        return redisConnectionFactory;   }​​    /**     * GenericObjectPoolConfig 连接池配置     *     * @return     */    @Bean("genericObjectPoolConfig")    public GenericObjectPoolConfig
genericObjectPoolConfig() {        GenericObjectPoolConfig
genericObjectPoolConfig = new GenericObjectPoolConfig<>();        genericObjectPoolConfig.setMaxIdle(maxIdle);        genericObjectPoolConfig.setMinIdle(minIdle);        genericObjectPoolConfig.setMaxTotal(maxActive);        genericObjectPoolConfig.setMaxWaitMillis(maxWait);        return genericObjectPoolConfig;   }}

 

然后在一篇文章中也看到,可能存在一个这样的问题,redis在长时间空闲状态,会自动重启?

本人没验证过,猜测可能是某种垃圾回收策略,内存碎片化整理。有兴趣的同学可以去研究一下。

 

那么本人再次怀疑,可能就是redis本身的config配置不对,因为笔者对于redis的自己的服务器上的部署都是全部自定义过的,也就是说,很多配置,都对其进行了适合自己项目的配置,比如回收策略,数据库数量,最大连接数量,等等等,那么按常理来说,redis的本身服务上也会有一个超时配置。

一找,果不其然有个超时配置;

但是这个配置是:客户端闲置N秒后关闭连接(0禁用)

按道理来说,0应该是禁用了主动关闭连接的配置

这里,我将尝试改为300s 后 超时

那么并且修改配置文件中的 多少秒检测一次空闲状态

 

修改这样,然后我后面再尝试运行一段时间,看看结果怎样

 

注意,此调试方案建议不要直接用于生产环境

因为每个公司服务的策略都不一样,毕竟脱离业务的架构方案都是耍流氓,建议可以以拓展知识面的方式阅读本文章。

转载地址:https://changemax.blog.csdn.net/article/details/113039842 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:mysql为什么需要优化
下一篇:0拷贝浅析

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月04日 10时51分52秒