我们都知道,HTTP协议采用“请求-应答”模式,当使用普通模式,即非Keep-alive模式时,每个请求/应答客户和服务器都要新建一个连接,完成之后立即断开连接(HTTP协议为无连接的协议);当使用Keep-alive模式时(又称持久连接,连接重用)时,Keep-alive功能使客户端到服务器端的连接持续有效,当出现对服务器的后续请求时,Keep-alive避免了重新建立连接。
在老的HTTP版本中,每个请求都将被创建一个新的客户端到服务器端的连接,在这个连接上发送请求,然后接受请求。这样的模式有一个很大的优点,它很简单,很容易理解和编程实现;它也有一个很大的缺点,它的效率很低,Keep-alive就是用来解决这个问题的。
Keep-alive使客户端到服务器端的连接持续有效,当出现对服务器的后续请求时,Keep-alive功能避免了建立或者重新建立连接。现在的大多数Web服务器都支持Keep-alive。对于提供静态内容的网站来说,这个功能通常很有用。但是,对于负担较重的网站来说,这里存在另一个问题:虽然为客户保留打开的连接有一定的好处,但它同样影响了性能,因为在处理暂停期间,本来可以释放的资源让旧被占用。此功能为HTTP1.1预设的功能,但在HTTP1.0上我们加上Keep-Aliveheader同样可以使用这个功能。
我们来举个例子说一下:
Keep-alive:timeout=5,max=100
意思是说:过期时间5秒,max是最多100次请求,强制断掉连接,也就是在timeout时间内每来一个新的请求,max会自动减1,直到为0,强制断掉连接。
在HTTP1.0版本中并没有官方的标准来规定Keep-alive如何工作,因此实际上他是被附加到HTTP1.0协议上的,如果客户端浏览器支持Keep-alive,那么就在HTTP请求中加一个字段:Connection:Keep-alive,当服务器收到附带有Connection:Keep-alive的请求时,它也会在响应头中加一个同样的字段来使用Keep-alive。这样一来客户端和服务器之间的HTTP连接就会保持,不会断开(除非超过timeout规定的时间),当客户端发送另外一个请求时,就使用这条已经建立的连接。
在HTTP1.1版本中,官方规定的Keep-alive使用标准和HTTP/1.0版本中有些不同,默认情况下HTTP/1.1中所有连接都被保持,除非在请求头或响应头中指明要关闭,:Connection:Close。
HTTP是一个无状态协议,这意味着每个请求都是独立的,Keep-alive没能改变这个结果。另外,Keep-alive也不能保证客户端和服务器端之间的连接一定是活跃的,在HTTP/1.1中也是如此。唯一能保证的就是当连接被关闭时你能得到一个通知,所以我们不应该让程序依赖Keep-alive的保持连接性,否则会与一些意想不到的后果。
通过使用Keep-alive机制,可以减少tcp连接建立的次数,也以为这可以减少TIME_WAIT状态连接,以此提高性能和提高HTTP服务器的吞吐率(更少的tcp连接意味着更少的系统内核调用,socket的accept()和close()调用)。但是长时间的tcp连接容易导致系统资源无效占用,配置不当的Keep-alive有事比重复利用连接带来的损失还更大。所以正确地设置Keep-alive timeout时间非常重要。
下面我们来说说这个Keep-alive timeout参数:
Httpd守护进程,一般都提供了Keep-alivetimeout时间设置参数。这个时间值意味着:一个http产生的tcp连接在传送完最后一个响应后,还需要还需要保持keep-alive timeout秒后,才开始关闭这个连接。
当httpd守护进程发送完一个响应后,理应马上主动关闭相应的tcp连接,设置keepalive_timeout后,httpd守护进程会说:再等等吧,看浏览器还有没有请求过来,这个等待的时间就是keepalive_timeout时间,如果守护进程在这个等待的时间里,一直没有收到浏览器发过来的http请求,则关闭这个http连接。
总之,我们应更好的使用这个机制给我们带来一些好处。