HTTP 协议是无状态的协议,即每一次请求都是互相独立的。因此它的最初实现是,每一个 http 请求都会打开一个 tcp socket 连接,当交互完毕后会关闭这个连接。
HTTP 协议是全双工的协议,所以建立连接与断开连接是要经过三次握手与四次挥手的。显然在这种设计中,每次发送 Http 请求都会消耗很多的额外资源,即连接的建立与销毁。
于是,HTTP 协议的也进行了发展,通过持久连接的方法来进行 socket 连接复用。
从图中可以看到:
在串行连接中,每次交互都要打开关闭连接 在持久连接中,第一次交互会打开连接,交互结束后连接并不关闭,下次交互就省去了建立连接的过程。 持久连接的实现有两种:HTTP/1.0+ 的 keep-alive 与 HTTP/1.1 的持久连接。
从1996年开始,很多 HTTP/1.0 浏览器与服务器都对协议进行了扩展,那就是 keep-alive 扩展协议。
注意,这个扩展协议是作为1.0的补充的“实验型持久连接”出现的。keep-alive 已经不再使用了,最新的 HTTP/1.1 规范中也没有对它进行说明,只是很多应用延续了下来。
使用 HTTP/1.0 的客户端在首部中加上 Connection:Keep-Alive,请求服务端将一条连接保持在打开状态。服务端如果愿意将这条连接保持在打开状态,就会在响应中包含同样的首部。如果响应中没有包含 Connection:Keep-Alive 首部,则客户端会认为服务端不支持 keep-alive,会在发送完响应报文之后关闭掉当前连接。
通过 keep-alive 补充协议,客户端与服务器之间完成了持久连接,然而仍然存在着一些问题:
HTTP/1.1 采取持久连接的方式替代了 Keep-Alive。
HTTP/1.1 的连接默认情况下都是持久连接。如果要显式关闭,需要在报文中加上 Connection:Close 首部。即在 HTTP/1.1 中,所有的连接都进行了复用。
然而如同 Keep-Alive 一样,空闲的持久连接也可以随时被客户端与服务端关闭。不发送 Connection:Close 不意味着服务器承诺连接永远保持打开。