HTTP keep-alive、TCP Keep-Alive、心跳检测,傻傻分不清?

WU双

共 2670字,需浏览 6分钟

 · 2021-06-02

聊技术,不止于技术

大家都知道HTTP 1.0和HTTP 1.1的区别在于连接复用,表现在协议里就是HTTP 1.1的请求头中会多一个 Connection: keep-alive,但是具体如何进行连接复用的可能很多同学并不是很清楚,今天我就通过抓包来具体解析HTTP 1.1协议,跟大家一起来看看连接复用到底是怎么一回事,跟随这个过程,同样也回答下HTTP keep-alive、TCP Keep-Alive以及心跳检测之间的区别。

1

先来说说HTTP keep-alive

首先问大家一个问题:浏览器刷新页面,可能会同时有多个请求发往后端服务器,每一个请求都会使用一个连接吗?
如果是使用HTTP 1.1协议的话,答案是否定的,因为连接会复用,不同的请求可以使用同一个连接,那具体一点呢?
其实Chrome浏览器对于同一个后端服务器最多有6个连接的限制。也就是说,无论你刷新的页面同时有多少个AJAX请求,Chrome只会限制这些请求最多通过6个TCP连接来完成。
举个例子,一个页面有10个AJAX请求,你此时刷新页面,浏览器会限制这10个请求通过6个TCP连接完成,这样就会有4个请求复用之前的连接。这其实就是HTTP 1.1中的keep-alive概念,也就是说TCP连接的复用,就是HTTP的keep-alive。
那什么时候后4个请求能够复用之前的连接呢?答案是之间的连接完成了一次完整的Request/Response,这样TCP连接中就没有脏数据,后面的请求自然能够复用此连接了。
下面我们就来看看HTTP keep-alive的实际抓包例子(IP地址末位37为浏览器端,40为服务器端):
上图中序号为382和序号为451的两个请求,就复用了一个连接,在序号为451的请求包中,标记了该连接中的上一个请求是382,并且从抓的包中也能够看出下一个请求是在上一个请求完成完整的Request/Response之后才发出的。这里也能够看出HTTP 1.1协议是半双工的,同一时刻,数据只在一个方向上收或发。
上面就是HTTP keep-alive中的连接复用的实际情况。

2

TCP Keep-Alive是什么?

与HTTP keep-alive有什么区别和联系

TCP Keep-Alive是TCP的保活功能,用来探测连接对端是否存在,属于传输层的概念,主要用来检测并关闭异常连接。
它与HTTP keep-alive没有任何联系,这两个完全是不同的概念。上面讲到的多个HTTP请求能够复用同一个连接就是HTTP keep-alive的概念,属于应用层的概念。
所以它们两个完全是不同的概念。

3

浏览器和服务端之间的连接会一直保持吗?

什么时候会关闭?

如果浏览器和服务端之间的连接如果一直保持会怎么样,答案是浪费资源,不仅仅会浪费服务端的资源,同样也会浪费客户端的资源,所以它们会在以下几种情况下关闭:
(1) 当Chrome浏览器关闭的时候,连接将会关闭,这属于客户端主动关闭连接的情况。
(2)当客户端长时间未操作,具体表现为连接长时间未传输数据的时候,服务端也会关闭连接,这属于服务端主动关闭的情况。
那么多长时间连接未传输数据,服务端就会关闭连接呢?这依赖于服务端的设置,如果服务端是Tomcat,keepAliveTimeout参数便是控制连接超时关闭的参数,当该参数设置为60s时,超过60s连接未传输数据,也就是说你超过60s未点击操作浏览器,服务端便会将连接关闭。
来看一个实际的例子:
上图中序号为2641的包是浏览器最后一次回复数据到服务端的包,大概是在20s的时刻,过了大概60s没有传输数据,所以在80s时刻的时候,服务端主动发送了fin包,断开了连接,对应的序号为6506,剩下的就是TCP四次挥手的包了。
(3)Chrome浏览器会通过TCP keep-alive来检测连接,如果检测连接失效,也就是服务端无响应,也会主动关闭连接。
我们也来看一个实际的例子。
首先在服务端所在机器执行以下命令,模拟客户端和服务端断网,即服务端无响应的情况:
iptables -A INPUT -p tcp -s 192.x.x.37 -j DROPiptables -A OUTPUT -p tcp -d 192.x.x.37 -j DROP
然后来看实际的抓包:
上图中可以看到,客户端在发送了多次TCP Keep-Alive检测包后(具体发送多少次,每次间隔时间多少依赖于具体的系统配置),服务端都没有响应,则发送RST包断开了连接。
上面就是连接关闭的几种情况,除了客户端关闭浏览器,还有服务端的超时检测机制,以及客户端的连接检测机制,这些机制都能够保证连接的有效性,防止无效连接过多从而占用系统资源。

4

TCP Keep-Alive与心跳检测有什么关系?

通过上面的实例,有同学可能发现TCP Keep-Alive和某些应用层协议的心跳检测很相似,确实如此。
TCP Keep-Alive的功能完全可以通过应用层的心跳检测功能来实现,并且能够更加灵活,因为TCP Keep-Alive功能还要依赖操作系统的设置,而应用层协议完全可以自己实现。它们本质上都是做了连接有效性检测的事。
所以它们只是做的事情相同,本身并没有什么关系。



写在最后

今天通过实际抓包,解析了HTTP 1.1中keep-alive的协议概念。顺便回答了HTTP keep-alive、TCP Keep-Alive及心跳检测之间的一些问题。
HTTP keep-alive是应用层的概念,表示不同的HTTP请求可以复用之前的连接。
TCP Keep-Alive是传输层的概念,属于TCP保活的功能,通过发送Keep-Alive包判断对端是否存在。
心跳检测也是应用层的概念,用来检测连接有效性。
通常TCP Keep-Alive与心跳检测只需要一个就可以了,毕竟它们做的事都是一样的。
希望今天的内容对大家有所帮助。

推荐阅读:
《Apache RocketMQ只用了7个类就实现了Nameserver,你知道是如何做到的吗?》



聊技术,不止于技术。

在这里我会分享技术文章、管理知识以及个人的思想感悟,欢迎点击关注。
公众号对话框回复【SACC】,获取大会精彩演讲PPT。
浏览 79
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报