http、tcp的keepalive那些事儿

HTTP keep-alive

早期网页比较简单,一次http请求便可加载到全部资源。随着网页愈来愈复杂,每每须要屡次请求才能加载到全部资源,网页上有css,html,图片等各类资源,短期内须要屡次http请求。每次http请求都须要创建tcp链接、发送请求、接收请求、断开链接等过程,很是耗系统资源.
css

能不能只创建一次http请求,同时请求css,html,图片等资源?确定是不能的,由于http是无链接的,若是同一个http请求连续请求css,html,js,图片等,返回的数据就不知道怎么处理了,不知道返回的内容是哪次请求须要的。
html

那既然tcp链接是有状态的,那能不能只创建一次tcp请求?毕竟tcp请求的握手和分手很是耗网络资源,http请求只是对tcp报文的一个封装,若是能复用tcp请求也能提高很多性能,答案是能够的。
通常用户进入一个网页、浏览网页须要一段时间,可是不会须要好久,所以http keep-alive通常不会设置太长,通常设置成1分钟,即一分钟以内对一个站点的访问只会创建一个tcp链接,页面上若是有多个http请求则会复用这个tcp链接。当没有http请求时,一分钟以后则断开则会个tcp链接。
mysql

http keep-alive底层的tcp实际上是短连接,它是经过心跳机制着tcp链接不间断
sql

http1.0默认是关闭的,经过http请求头设置“connection: keep-alive”进行开启;http1.1中默认开启,经过http请求头设置“connection: close”关闭
服务器

keep-alive机制:若开启后,在一次http请求中,服务器进行响应后,再也不直接断开TCP链接,而是将TCP链接维持一段时间。在这段时间内,若是同一客户端再次向服务端发起http请求,即可以复用此TCP链接,向服务端发起请求,并重置timeout时间计数器,在接下来一段时间内还能够继续复用。这样无疑省略了反复建立和销毁TCP链接的损耗。
markdown

http keep-alive是在服务端实现的,客户端只是设置了一下http头,加上keep-alive字段,服务端收到这个字段后不会立马关闭tcp链接,会保持一个设置的时长,好比1分钟,1分钟以内若是有新的tcp请求则重置这个时间,不然关闭这个tcp链接。通常服务端会设置两个参数:
网络

  • maxKeepAliveRequests:一个链接上,最多能够发起多少次请求,默认100,超过这个次数后会关闭。
  • keepAliveTimeout:底层socket链接最多保持多长时间,默认60秒,超过这个时间链接会被关闭。

通常的服务器端都会设置这两个参数,供http keep-alive使用,客户端只须要在http头中开启便可。
socket

TCP keepalive

tcp keepalive是tcp层面的长链接,它是真正的长链接,是传输层,这个tcp长链接可被上层全部协议使用,应用层协议对tcp的长链接无感知,并不直到tcp是长链接,只知道有可用的tcp链接而且使用便可。
tcp长链接默认是关闭的,须要开启。它有三个参数:
tcp

  • 保活时间(tcp_keepalive_time)默认:7200秒
  • 保活时间间隔(tcp_keepalive_intvl)默认:75秒
  • 探测循环次数(tcp_keepalive_probes)默认:9次

也就是默认状况下一条TCP链接在2小时(7200秒)都没有报文交换后,会开始进行保活探测,若再通过9*75秒=11分钟15秒的循环探测都未收到探测响应,即共计:2小时11分钟15秒后会自动断开TCP链接。
探测的结果可能有三种状况:
微服务

  • 对方回应了ACK。说明一切OK。若是接下来2小时尚未数据传输,那么还会继续发送keepalive探针,以确保链接存活。
  • 对方回复RST,表示这个链接已经不存在。例如一方服务宕机后重启,此时接收到探针,由于不存在对应的链接。
  • 没有回复。说明socket已经被关闭了

tcp的keepalive默认是关闭的,在建立链接的时候能够经过参数设置打开。可是tcp的keepalive通常设置太长,不太实用,通常应用程序本身经过心跳机制来维持着长链接。即tcp建立的时候不设置keepalive,默认它永远链接,它的断开由应用程序主动关闭,只要应用程序不关闭这个tcp链接就不会被断开。在复杂的网络环境下,经过应用程序心跳机制来确保链接保持着通畅,实现应用层的长链接。这是现代不少应用层保持长链接经常使用的技巧,好比mysql,微服务,服务发现等。

区别

  • TCP链接每每就是咱们广义理解上的长链接,由于它具有双端连续收发报文的能力,tcp链接没有长短之分,它只要创建起来了就会永远链接着,除非主动分手,可是因为网络问题,可能有一端会断开链接,这个时候另一端若是不感知,则会长时间维持着这个无效的链接。因此为了减小无效链接的维护,设置一个keepalive;开启了keep-alive的HTTP链接,也是一种长链接,可是它因为协议自己的限制,服务端没法主动发起应用报文。若是一个http请求结束,立刻关闭tcp链接或者长时间不关闭tcp链接,对系统资源都是一种消耗,所以设置一个keep-alive,让这个tcp链接在一段时间内保持着链接状态不要关闭,而这个时间长度是由服务器设置的。
  • TCP中的keepalive是用来保鲜、保活的,tcp原本就是长链接,须要主动关闭才会断开。为了监听对方是否网络一般才设置一个keepalive;HTTP中的keep-alive机制主要为了让支撑它的TCP链接活的的更久,因此一般又叫作:HTTP persistent connection(持久链接) 和 HTTP connection reuse(链接重用)

参考

【1】HTTP keep-alive和TCP keepalive的区别,你了解吗?
【2】详解HTTP 与TCP中Keep-Alive机制的区别

相关文章
相关标签/搜索