2团
Published on 2024-08-15 / 8 Visits
0
0

HTTP的keepalive与TCP的keepalive区别

1. 前言

最近在浏览知乎的时候发现了这个问题,觉得很有趣,在此处记录一下。

借用小林coding的回答:

  • HTTP 的 Keep-Alive,是由应用层(用户态) 实现的,称为 HTTP 长连接;

  • TCP 的 Keepalive,是由 TCP 层(内核态) 实现的,称为 TCP 保活机制。

2. TCP的keepalive

TCP Keepalive是一种机制,用于检测TCP连接是否仍然有效,即对方主机是否仍然可达。这个机制可以帮助识别和清理“死”连接,即那些在网络中断或对方主机崩溃后仍然打开的连接。TCP Keepalive通过定期发送探测消息给对方主机来工作。如果在一定时间内没有收到响应,连接被认为是死的,并且会被关闭。

2.1 工作原理

  1. 空闲时间:当TCP连接在一定时间(称为“Keepalive时间”)内没有数据传输时,TCP层会自动发送一个Keepalive探测包给对方。

  2. 探测尝试和间隔:如果对方没有响应这个探测包,TCP会继续发送更多的探测包。这些探测包之间的间隔时间以及尝试的次数也可以配置。

  3. 连接关闭:如果所有的探测包都没有得到响应,连接最终会被关闭。

2.2 主机配置

TCP Keepalive的行为可以通过操作系统进行配置。不同的操作系统提供了不同的配置接口,此处仅介绍Linux系统下配置。

查看当前设置:

sysctl net.ipv4.tcp_keepalive_time
sysctl net.ipv4.tcp_keepalive_intvl
sysctl net.ipv4.tcp_keepalive_probes

修改当前设置:

sysctl -w net.ipv4.tcp_keepalive_time=600
sysctl -w net.ipv4.tcp_keepalive_intvl=60
sysctl -w net.ipv4.tcp_keepalive_probes=10

在应用程序中,可以通过客户端选项,明确TCP连接启用keepalive,示例如下(Netty项目):

image-xllu.png

需要注意的是,TCP keepalive默认设置较为保守,具体如下所示:

image-knnr.png

因此,在实际应用场景中,多会启用定时心跳机制(例如默认五分钟),以维持客户端与服务端的TCP连接。

此外,在内网网络环境较好的情况下,建议修改主机的TCP keepliave设置(缩短心跳间隔,减少心跳探测次数),以保证中间件通信能够快速感知连接失效等异常情况。

3. HTTP的keepalive

HTTP Keep-Alive,也称为持久连接,是一种通信机制,它允许客户端和服务器在完成一次HTTP请求-响应后,保持TCP连接打开,以便用于后续的HTTP请求。这种机制减少了因为频繁建立和关闭连接而产生的开销,提高了HTTP通信的效率。

3.1 工作原理

  1. 连接复用:通过保持底层的TCP连接打开,HTTP Keep-Alive允许在同一连接上发送和接收多个HTTP请求/响应,而不是每次交换都打开一个新的连接。

  2. Connection头部:HTTP Keep-Alive通过HTTP头部Connection来控制。客户端在HTTP请求中包含Connection: keep-alive,表明它希望服务器保持连接打开。如果服务器支持Keep-Alive,它也会在响应中包含Connection: keep-alive

  3. 超时和最大请求数:服务器通常会为Keep-Alive连接设置超时时间和最大请求数限制。当超时时间到达或达到最大请求数后,服务器会关闭连接。

3.2 优点

  • 减少延迟:避免了每次请求都进行TCP三次握手的延迟。

  • 提高性能:减少了CPU和内存的使用,提高了连接的效率。

  • 更有效的网络利用:减少了TCP连接的开销,使网络资源得到更有效的利用。

3.3 示例

客户端请求示例,请求头中包含Connection: keep-alive

GET /index.html HTTP/1.1
Host: www.example.com
Connection: keep-alive

服务器响应示例,响应头中也包含Connection: keep-alive,并可能包含Keep-Alive头部,指示超时时间和最大请求数:

HTTP/1.1 200 OK
Date: Mon, 23 May 2022 22:38:34 GMT
Server: Apache/2.4.1 (Unix)
Connection: keep-alive
Keep-Alive: timeout=5, max=100
Content-Type: text/html
<html>
...
</html>

3.4 注意事项

  • 默认超时时间:浏览器默认的HTTP keepalive时长为60s,因此建议服务端的代理(例如Nginx)设置keepalive时长略大于60s;

  • Nginx的keepalive_requests

    • 在 HTTP 配置中,它控制 Nginx 与客户端之间 keep-alive 连接的请求次数;

    • 在 upstream 配置中,它控制 Nginx 与上游服务器之间 keep-alive 连接的请求次数;

    • 数值默认为100,满足常规web端代理场景;

    • 在HTTP 2代理场景中,因为协议的特殊性,需要放宽此数值以便充分利用http2特性(参考文章:漏洞处置:HTTP/2 快速重置攻击对 F5 NGINX 的影响


Comment