13 keep-alive 长连接

Posted by CodingWithAlice on April 25, 2021

13 keep-alive 长连接

  • 总结

    1、早期的 HTTP 协议使用短连接,收到响应后就立即关闭连接,效率很低

    2、HTTP/1.1 默认启用长连接,在一个连接上收发多个请求响应,提高了传输效率

    3、服务器会发送 Connection: keep-alive 字段表示启用了长连接

    4、报文头里如果有 Connection: close 就意味着长连接即将关闭

    5、过多的长连接会占用服务器资源,所以服务器会用一些策略有选择地关闭长连接

    6、队头阻塞 问题会导致性能下降,可以用 并发连接域名分片 技术缓解

早期 - 短连接

因为底层的数据传输基于 TCP/IP,每次发送请求前需要先与服务器建立连接,收到响应报文后会立即关闭连接

  • 缺点

    TCP 建立连接要有 三次握手,发送 3 个数据包,需要 1 个 RTT;关闭连接是 四次挥手,4 个数据包需要 2 个 RTT

    image-20210425204841180

长连接

长连接也称为持久连接 persistent connections /连接保活 keep alive /连接复用 connection reuse

image-20210425204928728

请求头/响应头

HTTP/1.1 中的连接都会 默认启用长连接:只要向服务器发送了第一次请求,后续的请求都会重复利用第一次打开的 TCP 连接

  • 也可以明确在 请求头 里要求使用长连接机制 - Connection: keep-alive
  • 不管客户端是否显式要求长连接,如果如果服务器支持长连接,它总会在 响应报文 里放一个Connection: keep-alive字段

长连接缺点

TCP 连接长时间不关闭,服务器必须在内存里保存它的状态,这就 占用了服务器的资源

所以长连接也需要在 恰当的时间关闭,方案有:

  • 1、在 客户端,可以在请求头里加上 Connection: close,告诉服务器:这次通信后就关闭连接;服务器 **看到这个字段后,在响应报文里也加上这个字段,发送之后就 **调用 Socket API 关闭 TCP 连接

  • 2、服务器端一般不会主动关闭长连接,但也有一些策略

    1⃣️ 使用 keepalive_timeout,设置 长连接的超时时间,如果在一段时间内连接上没有任何数据收发就主动断开连接,避免空闲连接占用系统资源

    2⃣️使用 keepalive_requests,设置长连接上 可发送的最大请求次数

队头阻塞

队头阻塞与短连接和长连接无关,而是由 HTTP 基本的 请求 - 应答 模型所导致的。

通俗解释:一个数据包影响了一堆数据包,它不来大家都走不了

image-20210425205035322

队头阻塞的优化方案

因为 请求 - 应答 模型不能变,所以 队头阻塞问题在 HTTP/1.1 里无法解决,只能缓解

  • 1、并发连接:同时对一个域名发起多个(6-8)长连接,用数量来解决质量 的问题
  • 2、域名分片:多开几个域名,指向同一台服务器