JedisConnectionException: java.net.SocketException: Broken pipe (Write failed) 问题排查
2022/8/20 14:24:33
本文主要是介绍JedisConnectionException: java.net.SocketException: Broken pipe (Write failed) 问题排查,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
问题描述
笔者有2个应用会不定时请求redis,其中一个应用大约每分钟请求一次,可以正常请求,但是另一个大约每小时请求一次的应用,经常出现Broken pipe (Write failed)
报错,具体报错信息如下:
redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Broken pipe (Write failed) at redis.clients.jedis.Connection.flush(Connection.java:282) at redis.clients.jedis.Connection.getBinaryMultiBulkReply(Connection.java:222) at redis.clients.jedis.Jedis.hgetAll(Jedis.java:780) ... Caused by: java.net.SocketException: Broken pipe (Write failed) at java.net.SocketOutputStream.socketWrite0(Native Method) at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111) at java.net.SocketOutputStream.write(SocketOutputStream.java:155) at redis.clients.util.RedisOutputStream.flushBuffer(RedisOutputStream.java:31) at redis.clients.util.RedisOutputStream.flush(RedisOutputStream.java:213) at redis.clients.jedis.Connection.flush(Connection.java:279) ... 26 more
问题定位
定位到redis服务端配置了3600秒的超时时间,即如果客户端连接超过3600秒空闲,那么就会被redis服务端主动清理掉。笔者大约每小时请求一次redis的应用,若请求时间间隔超过1小时,会被redis服务端认为连接是空闲的,然后把连接清理掉,此时客户端在去请求redis,就会出现报错: Broken pipe (Write failed)
。
解决方案
笔者首先尝试调大客户端socketTimout的超时时间,让客户端socketTimout的时间超过3600秒,如:7200秒。调整后发现,大约每小时请求一次redis的应用,仍然会出现 Broken pipe (Write failed)
报错。由此可见,当客户端和服务端都包含超时的配置时,redis会以服务端为准。
既然调整客户端的超时配置没有效果,服务端仍然会清理空闲的连接。那么客户端是否可以把服务端清理的连接,主动关闭掉呢?然后在需要时在重建连接。按照这个思路,笔者在每次请求redis前,会先执行ping操作。若ping成功了,说明socket连接还没被清理,可以直接请求redis;若ping 不成功,那么会抛出异常,捕获异常后在关闭客户端连接,后面在执行请求redis的命令时,会重新建立socket连接。以下是捕获异常后关闭连接的相关代码。
try { String result = jedis.ping(); LOGGER.debug("ping redis: {}", result); } catch (Exception e){ LOGGER.warn("ping failed, close jedis and reconnect, {}", e.getMessage()); try { jedis.close(); LOGGER.info("jedis closed"); } catch (Exception e1){ LOGGER.warn("close jedis failed, {}", e1.getMessage()); } }
通过上述方案,客户端空闲超过1小时后,向redis请求会抛出异常 Broken pipe (Write failed)
,程序捕获异常后关闭客户端连接,然后客户端重建连接,在执行请求就恢复正常了。
参考资料
- Redis客户端连接的空闲连接超时时间(timeout)的设置
这篇关于JedisConnectionException: java.net.SocketException: Broken pipe (Write failed) 问题排查的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-03-01沐雪多租宝商城源码从.NetCore3.1升级到.Net6的步骤
- 2024-11-18微软研究:RAG系统的四个层次提升理解与回答能力
- 2024-11-15C#中怎么从PEM格式的证书中提取公钥?-icode9专业技术文章分享
- 2024-11-14云架构设计——如何用diagrams.net绘制专业的AWS架构图?
- 2024-05-08首个适配Visual Studio平台的国产智能编程助手CodeGeeX正式上线!C#程序员必备效率神器!
- 2024-03-30C#设计模式之十六迭代器模式(Iterator Pattern)【行为型】
- 2024-03-29c# datetime tryparse
- 2024-02-21list find index c#
- 2024-01-24convert toint32 c#
- 2024-01-24Advanced .Net Debugging 1:你必须知道的调试工具