keepalive
TCP keep alive
TCP协议栈的keepalive
,连接空闲一定时间后,会进行保活探测
1 | [qisheng.li@YD-order-center-01 ~]$ sudo sysctl -a | grep keep |
tcp_keepalive_time
the interval between the last data packet sent (simple ACKs are not considered data) and the first keepalive probe; after the connection is marked to need keepalive, this counter is not used any further
连接空闲
tcp_keepalive_time
这么久之后,系统协议栈会认为连接需要保活tcp_keepalive_intvl
the interval between subsequential keepalive probes, regardless of what the connection has exchanged in the meantime
两次探测的间隔
tcp_keepalive_probes
the number of unacknowledged probes to send before considering the connection dead and notifying the application layer
探测次数
HTTP keep alive
从HTTP/1.1之后默认就使用keepalive了,http请求之后,连接不会关闭。这里只是实现了连接的复用,但是并没有保活相关的逻辑。
主要是通过header中的Connection: Keep-Alive
来实现连接的复用的,http/1.1之后默认就是keepalive,除非显式地声明为close。
parameters
A comma-separated list of parameters, each consisting of an identifier and a value separated by the equal sign (
'='
). The following identifiers are possible:
timeout
: indicating the minimum amount of time an idle connection has to be kept opened (in seconds). Note that timeouts longer than the TCP timeout may be ignored if no keep-alive TCP message is set at the transport level.max
: indicating the maximum number of requests that can be sent on this connection before closing it. Unless0
, this value is ignored for non-pipelined connections as another request will be sent in the next response. An HTTP pipeline can use it to limit the pipelining.
返回示例:
1 | HTTP/1.1 200 OK |
浏览器
那么 TCP 连接在发送后将仍然保持打开状态,这样浏览器就可以继续通过同一个 TCP 连接发送请求。保持 TCP 连接可以省去下次请求时需要建立连接的时间,提升资源加载速度。比如,一个 Web 页面中内嵌的图片就都来自同一个 Web 站点,如果初始化了一个持久连接,你就可以复用该连接,以请求其他资源,而不需要重新再建立新的 TCP 连接。
Nginx
1 | http { |
默认情况下,nginx已经自动开启了对client连接的keep alive支持。一般场景可以直接使用,但是对于一些比较特殊的场景,还是有必要调整个别参数。
需要修改nginx的配置文件(在nginx安装目录下的conf/nginx.conf):
1
2
3
4
5 > http {
> keepalive_timeout 120s 120s; // 默认75s
> keepalive_requests 10000; // 默认是100
> }
>
keepalive_timeout
第一个参数设置keep-alive客户端连接在服务器端保持开启的超时值。值为0会禁用keep-alive客户端连接。可选的第二个参数在响应的header域中设置一个值“Keep-Alive: timeout=time”。这两个参数可以不一样。
keepalive_requests
keepalive_requests指令用于设置一个keep-alive连接上可以服务的请求的最大数量。当最大请求数量达到时,连接被关闭。默认是100。
keepalive
The
*connections*
parameter sets the maximum number of idle keepalive connections to upstream servers that are preserved in the cache of each worker process. When this number is exceeded, the least recently used connections are closed.类似
maxIdle
Tomcat
配置名称 | 备注 |
---|---|
keepAliveTimeout |
The number of milliseconds this Connector will wait for another HTTP request before closing the connection. The default value is to use the value that has been set for the connectionTimeout attribute. Use a value of -1 to indicate no (i.e. infinite) timeout. |
maxKeepAliveRequests |
The maximum number of HTTP requests which can be pipelined until the connection is closed by the server. Setting this attribute to 1 will disable HTTP/1.0 keep-alive, as well as HTTP/1.1 keep-alive and pipelining. Setting this to -1 will allow an unlimited amount of pipelined or keep-alive HTTP requests. If not specified, this attribute is set to 100. |
HttpClient
apache的httpclient也没有保活的机制,连接的复用依赖于HTTP协议中的keep-alive
。HttpClient中有定时的任务,去清理过期和空闲的连接。
1 | /** |
归还连接时,根据response header中的来判断是否可以复用:
1 | // org.apache.http.impl.execchain.MinimalClientExec#execute |
ConnectionKeepAliveStrategy
1 | // org.apache.http.conn.ConnectionKeepAliveStrategy |
默认实现:
1 | // org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy |
ConnectionReuseStrategy
1 | // org.apache.http.ConnectionReuseStrategy |
默认实现:
1 | // org.apache.http.impl.DefaultConnectionReuseStrategy |
应用层
Dubbo
1 | // org.apache.dubbo.remoting.exchange.support.header.HeartbeatTimerTask#doTask |
Druid
在Druid-1.0.27之前的版本,DruidDataSource建议使用TestWhileIdle来保证连接的有效性,但仍有很多场景需要对连接进行保活处理。在1.0.28版本之后,新加入keepAlive配置,缺省关闭。
使用keepAlive功能,建议使用最新版本,比如1.1.21或者更高版本
Hikari CP
⏳
keepaliveTime
This property controls how frequently HikariCP will attempt to keep a connection alive, in order to prevent it from being timed out by the database or network infrastructure. This value must be less than themaxLifetime
value. A “keepalive” will only occur on an idle connection. When the time arrives for a “keepalive” against a given connection, that connection will be removed from the pool, “pinged”, and then returned to the pool. The ‘ping’ is one of either: invocation of the JDBC4isValid()
method, or execution of theconnectionTestQuery
. Typically, the duration out-of-the-pool should be measured in single digit milliseconds or even sub-millisecond, and therefore should have little or no noticible performance impact. The minimum allowed value is 30000ms (30 seconds), but a value in the range of minutes is most desirable. Default: 0 (disabled)
⏳
idleTimeout
This property controls the maximum amount of time that a connection is allowed to sit idle in the pool. This setting only applies whenminimumIdle
is defined to be less thanmaximumPoolSize
. Idle connections will not be retired once the pool reachesminimumIdle
connections. Whether a connection is retired as idle or not is subject to a maximum variation of +30 seconds, and average variation of +15 seconds. A connection will never be retired as idle before this timeout. A value of 0 means that idle connections are never removed from the pool. The minimum allowed value is 10000ms (10 seconds). Default: 600000 (10 minutes)
参考
- 03 | HTTP请求流程:为什么很多站点第二次打开速度会很快?
- brettwooldridge/HikariCP: 光 HikariCP・A solid, high-performance, JDBC connection pool at last.
- KeepAlive_cn · alibaba/druid Wiki
- Keep-Alive - HTTP | MDN
- Using TCP keepalive under Linux
- TCP Timers Chia-tai Tsai Introduction The 7 Timers for each Connection Connection-Establishment Timer Establish a new connection. - ppt download
- Using NGINX as an Accelerating Proxy for HTTP Servers
- Dubbo分析之心跳设计 - ksfzhaohui的个人页面 - OSCHINA - 中文开源技术交流社区
- 聊聊 TCP 长连接和心跳那些事 | 徐靖峰|个人博客
- 长连接 · Nginx 学习笔记
- Module ngx_http_upstream_module
- NGINX + TOMCAT出现大量的TIME-WAIT状态的TCP连接解决 - 小海bug的个人空间 - OSCHINA - 中文开源技术交流社区
- Apache Tomcat 8 Configuration Reference (8.5.64) - The HTTP Connector