HTTP 中 keep-alive :基本介绍

@李彪  May 24, 2018

背景介绍

  1. HTTP persistent connection(HTTP持久连接)又被称为HTTP keep-alive或者HTTP connection reuse,它的概要性想法就是用一次TCP连接接受或者发送多次HTTP请求,通过复用TCP,可以极大程度上降低建立TCP所需的资源与时间消耗,较新的HTTP / 2协议使用相同的思想,并进一步允许多个并发请求/响应通过单个连接复用。
  2. 启用Keep-Alive的优点

By opening and closing fewer TCP connections, CPU time is saved in routers and hosts (clients, servers, proxies, gateways, tunnels, or caches), and memory used for TCP protocol control blocks can be saved in hosts.
HTTP requests and responses can be pipelined on a connection. Pipelining allows a client to make multiple requests without waiting for each response, allowing a single TCP connection to be used much more efficiently, with much lower elapsed time.

Network congestion is reduced by reducing the number of packets caused by TCP opens, and by allowing TCP sufficient time to determine the congestion state of the network.
Latency on subsequent requests is reduced since there is no time spent in TCP's connection opening handshake.
HTTP can evolve more gracefully, since errors can be reported without the penalty of closing the TCP connection. Clients using future versions of HTTP might optimistically try a new feature, but if communicating with an older server, retry with old semantics after an error is reported.

RFC 2616 (P47)还指出:单用户客户端与任何服务器或代理之间的连接数不应该超过2个。一个代理与其它服务器或代码之间应该使用不超过2 * N的活跃并发连接。这是为了提高HTTP响应时间,避免拥塞(冗余的连接并不能代码执行性能的提升)。

运行模式简介

  1. 在HTTP 1.0下:默认不会开启持久性连接,只有头部包含了keep-alive,虽然官方没有给与相关说明,但是它已经被添加进现有的协议中。如果客户端需要保持连接,则会向请求头部添加keep-alive字段,服务器收到相关字段后也会自动回复一个同样字段。在此之后,连接不会丢失,持续保持打开状态。当客户端发起另一个请求时,会复用这个TCP连接,这将持续到客户端与服务端会话结束、或者有一方断开连接。
  2. 在HTTP 1.1下:除非特殊声明,否则默认开启持久性连接。HTTP持久连接不使用单独的keepalive消息,它们只允许多个请求使用单个连接。但是Apache httpd 1.3和2.0的默认连接超时时间仅为15秒,Apache httpd 2.2及更高版本仅为5秒。短暂超时的优点是能够快速传递网页的多个组件,而不会耗费资源来运行多个服务器进程或线程的时间过长。
  3. Keepalive with chunked transfer encoding:Keepalive使客户端难以确定一个响应结束和下一个响应何时开始,特别是在流水线HTTP操作期间。Content-Length由于流式传输而无法使用时,这是一个严重的问题。为了解决这个问题,HTTP 1.1引入限定了一个分块传输的编码last-chunk位。该last-chunk位设置在每个响应的结尾,以便客户端知道下一个响应开始的位置。(这部分详解请看最后分析

优点

  1. 后续请求中的延迟减少(无握手)。
  2. 由于较少的新连接和TLS握手,减少了CPU使用率和往返次数。
  3. 启用请求和响应的HTTP流水线。
  4. 减少网络拥塞(较少的TCP连接)。
  5. 可以报告错误而不会导致关闭TCP连接。

缺点

如果客户端在收到所有需要的数据时未关闭连接,则保持服务器上的连接打开所需的资源将不可用于其他客户端。这会影响服务器的可用性以及资源不可用的时间取决于服务器的体系结构和配置。

在网页浏览器中使用

  1. 多重连接与永久连接的模式。所有现代Web浏览器,包括Google Chrome,Firefox,Internet Explorer(自4.01),Opera(自4.0)和Safari都使用持久连接。
  2. 默认情况下,Internet Explorer版本6和7使用两个持久连接,而版本8使用六个。[13]不活动的60秒后持久连接超时这是通过Windows注册表改变。
  3. 在Firefox中,同时连接的数量可以自定义(每个服务器,每个代理,总数)。持续连接超过115秒(1.92分钟)后可以通过配置更改不活动时间。

客户端如何判断消息内容的长度或大小?

一般我们会想到content-length字段,对于静态网页或者资源,这个字段可以很清晰的告知我们资源的大小,但是对于动态网页,服务器并不能一下子告诉我们资源的大小,所以需要使用消息首部字段Transfer-Encoding,在动态网页模式下,服务端会采用chunk模式来把所需传送的文件进行分块化、chunk编码将数据分成一块一块的发生。Chunked编码将使用若干个Chunk串连而成,由一个标明长度为0 的chunk标示结束。

每个Chunk分为头部和正文两部分,头部内容指定正文的字符总数(十六进制的数字 )和数量单位(一般不写),正文部分就是指定长度的实际内容,两部分之间用回车换行(CRLF) 隔开。在最后一个长度为0的Chunk中的内容是称为footer的内容,是一些附加的Header信息(通常可以直接忽略)


评论已关闭