将 httpclient jar 版本升级到 4.5.3 时出现 socketException 断管

socketException broken pipe upon upgrading httpclient jar version to 4.5.3

我在客户端收到管道损坏的套接字异常。

[write] I/O error: Connection has been shutdown: javax.net.ssl.SSLException: java.net.SocketException: Broken pipe (Write failed) [LoggingManagedHttpClientConnection::shutdown] http-outgoing-278: Shutdown connection 1520546494584[20180308 23:01:34] [ConnectionHolder::abortConnection] Connection discarded 1520546494584[20180308 23:01:34] [BasicHttpClientConnectionManager::releaseConnection] Releasing connection [Not bound]

似乎是 httpclient jar 的升级引起了问题。

httpclient-4.3.2 没有问题

异常每 2 分钟出现一次。问题有时是间歇性的。

之后,发送 expect:100-continue,conn.flush 抛出异常

客户端和服务器是Linux机器

客户端使用 http jar 向服务器 REST 发出请求。

请帮助我调试问题

httpjar 会导致此类问题吗?

连接管理器保持活动状态的持久连接变得陈旧。也就是说,目标服务器在其端关闭连接而 HttpClient 无法对该事件作出反应,同时连接处于空闲状态,从而呈现连接 half-closed 或 'stale' 这是 Java 中阻塞 I/O 的一般限制。除了尝试从套接字读取外,根本没有办法查明对端端点是否已关闭连接。

如果使用陈旧的连接来传输请求消息,则请求执行通常会在写入操作中失败并出现 SocketException 并自动重试。 Apache HttpClient 通过使用过时的连接检查来解决这个问题,这实际上是一个非常简短的读取操作。但是,检查可以而且经常被禁用。事实上,由于检查引入的额外延迟,通常建议禁用它。 旧连接的处理在 4.4 版中发生了变化。以前,代码会在 re-using 之前默认检查每个连接。如果自上次使用连接以来经过的时间超过已设置的超时,代码现在仅检查连接。默认超时设置为 2000ms