【问题标题】:Apache HttpClient connection configurationApache HttpClient 连接配置
【发布时间】:2019-02-04 11:32:18
【问题描述】:
【问题讨论】:
标签:
java
connection-pooling
apache-httpclient-4.x
【解决方案1】:
根据:https://hc.apache.org/httpcomponents-client-4.5.x/current/tutorial/html/connmgmt.html#d5e418
HttpClient 试图通过测试是否
连接“陈旧”,不再有效,因为它已关闭
在服务器端,在使用连接执行
HTTP 请求。陈旧的连接检查不是 100% 可靠的。这
唯一可行的解决方案,不涉及每个套接字一个线程
空闲连接的模型是用于驱逐的专用监视器线程
由于长时间的连接而被视为过期的连接
不活动。监控线程可以定期调用
ClientConnectionManager#closeExpiredConnections() 方法关闭所有
过期的连接并从池中逐出关闭的连接。它还可以选择性地调用 ClientConnectionManager#closeIdleConnections() 方法来关闭所有在给定时间段内空闲的连接。
expired和idle的区别在于,一个过期的连接已经在服务端关闭了,而idle的连接不一定在服务端关闭,而是闲置了一段时间。当一个连接关闭时,它会在要使用的池中再次可用。
【解决方案2】:
HTTP 基于 TCP,它管理包以正确的顺序发送和接收,如果包在中途丢失,则请求重新传输。 TCP 连接以包含 SYN、SYN-ACK 和 ACK 消息的 TCP 握手开始,而以 FIN、ACK-FIN 和 ACK 系列结束,从这张图片可以看出取自Wikipedia
虽然 HTTP 是一种请求-响应协议,但打开和关闭连接的成本很高,因此 HTTP/1.1 允许重用现有连接。使用标题Connection: keep-alive 即告诉您的客户端(即浏览器)保持与服务器的连接打开。一台服务器可以同时拥有成千上万个打开的连接。为了避免耗尽服务器的资源,通常会及时限制连接。通过套接字超时,空闲连接或具有某些连接问题(互联网访问中断,...)的连接会在一些预定义的时间后由服务器自动关闭。
许多 HTTP 实现,例如 Apaches HTTP 客户端 4.4 及更高版本,仅在即将使用连接时检查连接状态。
4.4 版更改了旧连接的处理方式。以前,代码会在重新使用之前默认检查每个连接。该代码现在仅在自上次使用连接后经过的时间超过已设置的超时时才检查连接。默认超时设置为 2000 毫秒 (Source)
如果一个连接可能有一段时间没有被使用,那么客户端可能没有从服务器读取ACK-FIN,因此当它实际上已经被服务器关闭时仍然认为连接是打开的。这样的连接已过期,通常称为半关闭。因此它可能会被池收集。
请注意,如果您发送包含Connection: close HTTP 标头的请求,则应在客户端收到响应后立即关闭连接。
可以通过netstat 检查打开连接的状态,大多数现代操作系统上都应该有这个netstat。我最近不得不检查我们的一个 HTTP 客户端,该客户端是通过第三方库管理的,该库没有正确传播 Connection: Close 标头,因此导致大量半关闭连接。