说句不客气的话,小编大大小小的面试经历的几十场,也算是半个面霸了。但是第一次遇到这个问题还是有点懵。首先我们需要知道的是TCP的 KeepAlive和HTTP的Keep-Alive是两个完全不同的概念,而且两个的写法都不一样,不能混为一谈,含义更是大相径庭。
- TCP的KeepAlive,是由 TCP 层(内核态)实现的,称为 TCP 保活机制。
- HTTP的Keep-Alive,是由应用层(用户态) 实现的,称为 HTTP 长连接。
TCP的KeepAlive
如果直接问大家TCP的KeepAlive是什么估计很多人都答不上来,但是问另外一个东西相信大家就很熟悉了,那就是心跳包。心跳包这个东西就很常见了,比如我们的RocketMQ,再比如说我们的各种服务发现组件,都实现的维系心跳的功能。所以简单地说TCP的KeepAlive就是一个维持心跳,维护长连接的过程,同时及时释放异常的半连接。
TCP的KeepAlive是侧重在保持客户端和服务端的连接,一方会定时发送心跳包给另一方,当一方断掉的时候,另外一方定时发送几次心跳包,如果连续几次对方都返回的是RST,而不是ACK,那么就释放当前链接。
此时我们假设一下,如果TCP没有KeepAlive机制会出现什么问题呢。一旦对方断开连接,而另一方没有释放的话,不出三天,服务器资源就会被挤爆。说到这里是不是感觉这种场景似曾相识呢,此时我们就会发现这种场景和TCP三次握手时候的半连接攻击如出一辙。
大致流程如下:
1.如果对方主机不可达,一般在建立连接之前就会出错。
2.如果对方主机可达,应用程序正常,对方响应ACK应答,就认为是存活的。
3.如果对方主机可达,应用程序退出,对方响应RST应答,发送TCP撤消连接。
4.如果对方主机可达,应用程序崩溃,对方响应FIN应答。请求释放连接。
5.如果对方主机无响应,即同时无ACK, RST,那么就会持续发送,直到超时。此时开始撤消连接。这个时间一般默认为两个小时。
举例说明:
这里是小编在git上面找的一个开源项目,截取了一小部分代码。
SO_KEEPALIVE:KeepAlive控制开关,打开或关闭。
TCP_KEEPIDLE:设置空闲时间,即有多久没有发送报文就进行探测。
TCP_KEEPCNT:设置KeepAlive的尝试次数,
TCP_KEEPINTVL:设置重试KeepAlive的报文间隔。
需要注意的是TCP_KEEPIDLE和TCP_KEEPINTVL是不一样的,前者是需要进行KeepAlive探测的空闲时间,而后者是在某次KeepAlive探测失败,再次重试的间隔时间。
对于上面的代码段来说,当该TCP连接有5秒没有进行数据传输时,就会发送KeepAlive探测报文。当探测报文失败时,会隔2秒再次发送探测报文,3次探测失败就判断连接失败。
HTTP的Keep-Alive
众所周知HTTP/1.0,默认使用的是短连接。也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。这是因为早期的Web请求比较简单,大部分是图文,一次性将页面所需要的数据全部加载,然后页面渲染。但是随着互联网的发展,出现了各种各样比较复杂的场景,最常见的就是在线视频,在线游戏等等。那么此时如果还是短链接,就会频繁地建立销毁链接,占用大量的资源。于是乎HTTP/1.1便开始默认长连接了。此时此刻我们的主角Keep-Alive该上场了。
怎么理解Keep-Alive呢,我们的直观感受就是一个标记而已,当开启Keep-Alive后,HTTP连接不会立马断开,而是可以被下一个请求继续复用,这就省去了频繁的创建和销毁。同样的,在接收完响应报文后,客户端也不关闭连接,发送下一个 HTTP 请求时会重用该连接。
在 HTTP/1.0 协议中,如果请求头中包含:
Connection: Keep-Alive
前面我们说过HTTP/1.0默认的是短连接,但是如果在请求头中加上Connection: Keep-Alive理论上是可以实现长连接的,不过这个默认不开启。
在 HTTP/1.1 协议中,默认开启 keep-alive,除非显式地关闭它:
Connection: clos
举例说明:
任意取一个响应报文。
由上面的示例可以看到里面的响应头部有一个Connection: Keep-Alive,这个键值对的作用是让HTTP保持连接状态,因为HTTP 协议采用“请求-应答”模式,当使用普通模式,即非 Keep-Alive 模式时,每个请求/应答客户和服务器都要新建一个连接,完成之后立即断开连接(HTTP 协议为无连接的协议);当使用 Keep-Alive 模式时,Keep-Alive 功能使客户端到服务器端的连接持续有效。
在HTTP 1.1版本后,默认都开启Keep-Alive模式,只有加入加入 Connection: close才关闭连接,当然也可以设置Keep-Alive模式的属性,例如 Keep-Alive: timeout=5, max=100,表示这个TCP通道可以保持5秒,max=100,表示这个长连接最多接收100次请求就断开。
总结
这里只是简单地介绍了一下两者的区别,足够应付面试了。如果要深入了解,必然是涉及TCP和HTTP底层的,一天一夜也说不清楚。这里只需要明白两者是干什么的就行,大致区别即可,当然如果要了解更多的网络面试知识,可以关注一下小编,后续小编会不定时更新的。
福利赠送
又到了大家期待的福利时间了。本次说的是大厂的面试环节,那么赠送的也是和大厂的面试环节相关的。那就是几十份真实的大厂面试笔录,包含答案。
说了这么多,各位看官大人要怎么获取呢。很简单,关注小编,私信「资料」即可获得免费获取方式。
如果大家有比较好的资源欢迎相互交流,共同提高。同时有部分素材来源于网络,如侵,联删。