【工作笔记】-Jedis连接池配置排雷,java.net.SocketException: 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;

设置了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;
    }

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

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

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

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值