当前位置:   article > 正文

【工作笔记】-Jedis连接池配置排雷,java.net.SocketException: Broken pipe_jedis broken pipe

jedis broken pipe

业务中使用到了Jedis连接池,近期生产业务频繁出现“java.net.SocketException: Broken pipe”的异常堆栈信息,虽然没有影响到生产业务,但是非常烦人,打算来排除一下问题。

这类问题一般是Jedis客户端与服务端之间的服务连接断开了,但是连接池没有及时检测出来,导致坏链一直保存在池中,业务从连接池中取出坏链,导致抛异常。

看一下连接池的配置:

		JedisPoolConfig poolConfig = new JedisPoolConfig();
		poolConfig.setMaxIdle(PropsUtils.redisPoolMaxIdle);
		poolConfig.setMaxIdle(PropsUtils.redisPoolMinIdle);
		poolConfig.setMaxTotal(PropsUtils.redisPoolMaxTotal);
		poolConfig.setBlockWhenExhausted(PropsUtils.redisPoolBlockWhenExhausted);
		poolConfig.setMaxWaitMillis(PropsUtils.redisPoolMaxWaitMillis);
		poolConfig.setTestWhileIdle(PropsUtils.redisPoolTestOnIdle);
	    poolConfig.setTimeBetweenEvictionRunsMillis(PropsUtils.redisPoolTimeBetweenEvictionRunsMillis);
		return poolConfig;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

设置了TestWhileIdle以及TimeBetweenEvictionRunsMillis,没有设置TestOnBorrow和TestOnReturn.

最简单粗暴的做法应该是直接添加TestOnBorrow和TestOnReturn两项配置为true,可以直接解决问题。

但是这两项配置对性能影响很大,不是最佳实践。 按照规范来说,配置了TestWhileIdle应该足以能够检测出坏链了,为何没有生效。

跟代码看一下TestWhileIdle的执行逻辑:

    @Override
    public boolean evict(final EvictionConfig config, final PooledObject<T> underTest,
            final int idleCount) {

        if ((config.getIdleSoftEvictTime() < underTest.getIdleTimeMillis() &&
                config.getMinIdle() < idleCount) ||
                config.getIdleEvictTime() < underTest.getIdleTimeMillis()) {
            return true;
        }
        return false;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

只有在当前空闲连接数大于minIdle的时候,才会执行坏链的驱逐。

再看我的minIdle配置,是10, 也就是说,当前业务负载如果比较低,连接数少于10,即使其中有一个空闲坏链, 也无法将其驱逐, 导致业务拿到坏链。

修改将minIdle的配置删除,保持默认配置0,即可解决问题。

P.S. “ java.net.SocketException: Broken pipe”异常只在生产环境有, 测试环境不出现,因为生产环境带了F5,并且定期关闭链接,而测试环境则不会。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/160138
推荐阅读
相关标签
  

闽ICP备14008679号