1)概述:性能与短链接、长连接
1)长连接能尽量减少tcp握手、挥手的次数,从而提升性能。
2)短链接为每一个http请求进行tcp握手、挥手,性能损耗大。
2)短链接
HTTP (0.9/1.0)协议是个非常简单的协议,通信过程采用了简单的“请求 - 应答”方式。
它底层的数据传输基于 TCP/IP,每次发送请求前需要先与服务器建立连接,客户端收到响应报文后会[ 立即关闭tcp连接 ]。客户端与服务器的整个连接过程很短暂,所以就被称为"短连接"(shortlived connections)。短连接的缺点相当严重,因为在 TCP 协议里,建立连接和关闭连接都是非常"昂贵"的操作。
3)长连接(HTTP/1.1默认启用长连接)
HTTP 1.1协议就提出了“长连接”的通信方式,也叫"持久连接"(persistentconnections)、“连接保活”(keep alive)、“连接复用”(connection reuse)。思路上,用的就是"成本均摊"的思路,既然 TCP 的连接和关闭非常耗时间,那么就把这个时间成本由原来的一个"http请求 - http应答"均摊到多个"http请求 - http应答"上。虽然不能改善 TCP 的连接效率,但每个"http请求 - http应答"的无效时间就会降低不少,整体效率也就提高了。长连接的效果如下图所示:
4)长连接的小缺点(因此长连接也需要[ 在恰当的时间 ]关闭)
因为 TCP 连接长时间不关闭,服务器必须在内存里保存连接的状态,其实就是占用了服务器的资源。如果有大量的空闲长连接只连不发,就会很快耗尽服务器的资源。
所以,长连接需要[ 在恰当的时间 ]关闭 。关闭长连接,这在客户端或者服务器都能做到。
在客户端侧,可以在请求头里加上"Connection: close"字段,告诉服务器:“这次通信完成后就关闭tcp连接”。服务器看到这个字段,就知道客户端要主动关闭连接,于是在响应报文里也加上这个"Connection: close"字段,响应发送完毕后则调用Socket API关闭该TCP连接。
服务器端通常不会主动关闭tcp连接,但具备一些关闭长连接的策略。拿 Nginx 这种服务器来举例,它有两种方式:
- 使用"keepalive_timeout"指令,设置长连接的超时时间,如果在一段时间内tcp连接上没有任何数据流动则主动断开该tcp连接,从而避免空闲tcp连接占用服务器资源。
- 使用"keepalive_requests"指令,设置一个长连接上可发送的最大http请求次数。比如设置成 N,那么当 Nginx 在这个连接上处理了 N个请求后,也会主动断开该长连接。
5)连接的相关头字段
HTTP/1.1中的连接都会默认启用长连接。客户端不需要用头字段指定,只要向服务器发送了第一次请求,后续的http请求都会重复利用第一次打开的TCP连接,直到这个TCP连接被关闭。当然,也可在请求头里明确地要求使用长连接机制,使用的头字段是Connection: “keep-alive”。不过不管客户端是否显式要求长连接,如果服务器支持长连接,它总会在响应报文里放一个Connection: "keep-alive"头字段,告诉客户端: “我服务器是支持长连接的,接下来的http请求就复用这个TCP连接。”