简体   繁体   English

Apache HttpClient连接配置

[英]Apache HttpClient connection configuration

I am trying to setup a HttpClient through the HttpClientBuilder . 我试图建立一个HttpClient的通过HttpClientBuilder I also had a look at the HttpClientConnectionManager and here the confusion started. 我也看了看HttpClientConnectionManager ,这里的混乱就开始了。

On the ConnectionManager or more exactly the PoolingHttpClientConnectionManager there are methods to: 在ConnectionManager或更确切地说在PoolingHttpClientConnectionManager上,有一些方法可以:

  • close expired connections 关闭过期的连接
  • close idle connections 关闭空闲连接

When is a connection considered expired? 连接何时被视为过期?
When is it idle? 什么时候闲着?
What happens when a connection from the pool is closed? 当池中的连接关闭时会发生什么? Is it ensured, that there are connections recreated when needed? 是否确保在需要时重新创建了连接?

According to: https://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html 根据: https : //hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html

HttpClient tries to mitigate the problem by testing whether the connection is 'stale', that is no longer valid because it was closed on the server side, prior to using the connection for executing an HTTP request. HttpClient尝试通过在使用连接执行HTTP请求之前测试该连接是否为“过时的”(不再有效,因为该连接已在服务器端关闭)来缓解此问题。 The stale connection check is not 100% reliable. 过时的连接检查不是100%可靠的。 The only feasible solution that does not involve a one thread per socket model for idle connections is a dedicated monitor thread used to evict connections that are considered expired due to a long period of inactivity. 唯一不涉及每个套接字模型一个线程用于空闲连接的可行解决方案是专用监视器线程,该线程用于退出由于长时间不活动而被视为过期的连接。 The monitor thread can periodically call ClientConnectionManager#closeExpiredConnections() method to close all expired connections and evict closed connections from the pool. 监视线程可以定期调用ClientConnectionManager#closeExpiredConnections()方法以关闭所有过期的连接,并从池中逐出关闭的连接。 It can also optionally call ClientConnectionManager#closeIdleConnections() method to close all connections that have been idle over a given period of time. 它还可以选择调用ClientConnectionManager#closeIdleConnections()方法来关闭在给定时间内空闲的所有连接。

The difference between expired and idle is that an expired connection has been closed on the server side, while the idle connection isn't necessarily closed on the server side, but it has been idle over a period of time. 过期和空闲之间的区别在于,过期的连接已在服务器端关闭,而空闲连接不一定在服务器端已关闭,但已在一段时间内处于空闲状态。 When a connection is closed, it becomes available again in the pool to be used. 关闭连接后,该连接将在要使用的池中再次变为可用。

HTTP is based on TCP, which manages that packages are sent and received in the correct order and requests retransmissions if packages got lost mid way. HTTP基于TCP,TCP管理以正确的顺序发送和接收包,如果包在途中丢失,则请求重传。 A TCP connection is started with a TCP-Handshake consisting of SYN , SYN-ACK and ACK messages while it is ended with a FIN , ACK-FIN , and ACK series as can be seen from this image taken from Wikipedia TCP连接以包含SYNSYN-ACKACK消息的TCP握手开始,而以FINACK-FINACK系列结尾,如从Wikipedia上获取的图像所示 在此处输入图片说明

While HTTP is a request-response protocol, opening and closing connections is quite costly and so HTTP/1.1 allowed to reuse existing connections. 虽然HTTP是一种请求-响应协议,但是打开和关闭连接的成本很高,因此HTTP / 1.1允许重用现有的连接。 With the header Connection: keep-alive ie you tell your client (ie browser) to keep the connection open to a server. 使用标题Connection: keep-alive即您告诉客户端(即浏览器)保持与服务器的连接打开。 A server can have litterally thousands and thousands open connection at the same time. 一台服务器可以同时拥有成千上万个打开的连接。 In order to avoid draining the server's resources connection are usually timely limited. 为了避免耗尽服务器的资源,通常会及时限制连接。 Via socket timeouts idle connections or connections with certain connection issues (broken internet access, ...) are closed after some predefined time by the server automatically. 通过套接字超时,空闲服务器或具有某些连接问题的连接(互联网访问断开等)在服务器经过预定时间后会自动关闭。

Plenty of HTTP implementations, such as Apaches HTTP client 4.4 and beyond, check the status of a connection only when it is about to use it. 许多HTTP实现(例如Apache的HTTP客户端4.4及更高版本)仅在连接将要使用时才检查其状态。

The handling of stale connections was changed in version 4.4. 过时的连接的处理在版本4.4中进行了更改。 Previously, the code would check every connection by default before re-using it. 以前,该代码默认情况下会在重新使用之前检查每个连接。 The code now only checks the connection if the elapsed time since the last use of the connection exceeds the timeout that has been set. 现在,该代码仅在自上次使用连接以来所经过的时间超过已设置的超时时,才检查连接。 The default timeout is set to 2000ms ( Source ) 默认超时设置为2000ms( Source

If a connection therefore might not have been used for some time the client may not have read the ACK-FIN from the server and therefore still think the connection is open when it actually got already closed by the server some time ago. 因此,如果一段时间未使用连接,则客户端可能尚未从服务器读取ACK-FIN ,因此,当服务器实际上已经关闭连接时,仍会认为该连接已打开。 Such a connection is expired and usually called half-closed. 这样的连接已过期,通常称为半关闭。 It therefore may be collected by the pool. 因此,它可能会被池收集。

Note that if you send requests including a Connection: close HTTP header, the connection should be closed right after the client received the response. 请注意,如果您发送包含Connection: close HTTP标头的请求,则应在客户端收到响应后立即关闭连接。

The state of open connections can be checked via netstat which should be present on most modern operation systems. 可以通过netstat来检查打开的连接状态, netstat应该在大多数现代操作系统中都存在。 I recently had to check one of our HTTP clients which was managed through a third party library that did not propagate the Connection: Close header properly and therefore led to plenty of half-closed connections. 最近,我不得不检查通过第三方库管理的HTTP客户端之一,该第三方库未正确传播Connection: Close标头,因此导致大量的半关闭连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM