HTTP 的连接管理也算得上是个“老生常谈”的话题了,你一定曾经听说过“短连接”“长连接”之类的名 词,今天让我们一起来把它们弄清楚
# 什么是短链接
HTTP 协议最初(0.9/1.0)是个非常简单的协议,通信过程也采用了简单的“请求-应答”方式。 它底层的数据传输基于 TCP/IP,每次发送请求前需要先与服务器建立连接,收到响应报文后会立即关闭连 接。 因为客户端与服务器的整个连接过程很短暂,不会与服务器保持长时间的连接状态,所以就被称为“短连 接”(short-lived connections)。早期的 HTTP 协议也被称为是“无连接”的协议
短连接的缺点相当严重,因为在 TCP 协议里,建立连接和关闭连接都是非常“昂贵”的操作。TCP 建立连接 要有“三次握手”,发送 3 个数据包,需要 1 个 RTT;关闭连接是“四次挥手”,4 个数据包需要 2 个 RTT。 而 HTTP 的一次简单“请求-响应”通常只需要 4 个包,如果不算服务器内部的处理时间,最多是 2 个 RTT。这 么算下来,浪费的时间就是“3÷5=60%”,有三分之二的时间被浪费掉了,传输效率低得惊人
# 什么是长连接
短链接的缺点显而易见,客户端和服务端每交互一次都要建立 TCP 链接,十分浪费服务器资源。针对短连接暴露出的缺点,HTTP 协议就提出了 “长连接” 的通信方式
其实解决办法也很简单,用的就是“成本均摊”的思路,既然 TCP 的连接和关闭非常耗时间,那么就把这个
时间成本由原来的一个“请求-应答”均摊到多个“请求-应答”上;如图所示

# 连接相关的头字段
由于长连接对性能的改善效果非常显著,所以在 HTTP/1.1 中的连接都会默认启用长连接。不需要用什么特殊 的头字段指定,只要向服务器发送了第一次请求,后续的请求都会重复利用第一次打开的 TCP 连接,也就是 长连接,在这个连接上收发数据。
# 队头阻塞
“队头阻塞”与短连接和长连接无关,而是由 HTTP 基本的“请求-应答”模型所导致的。
因为 HTTP 规定报文必须是“一发一收”,这就形成了一个先进先出的“串行”队列。队列里的请求没有轻
重缓急的优先级,只有入队的先后顺序,排在最前面的请求被最优先处理。
如果队首的请求因为处理的太慢耽误了时间,那么队列里后面的所有请求也不得不跟着一起等待,结果就是
其他的请求承担了不应有的时间成本
比如:
在上班的时间点上,大家都在排队打卡,可这个时候偏偏最前面的那个人遇到了打卡机故障,怎么也不能打卡
成功,急得满头大汗。等找人把打卡机修好,后面排队的所有人全迟到了
# 性能优化
因为“请求-应答”模型不能变,所以“队头阻塞”问题在 HTTP/1.1 里无法解决,只能缓解,有什么办法 呢? 公司里可以再多买几台打卡机放在前台,这样大家可以不用挤在一个队伍里,分散打卡,一个队伍偶尔阻塞 也不要紧,可以改换到其他不阻塞的队伍。 这在 HTTP 里就是“并发连接”(concurrent connections),也就是同时对一个域名发起多个长连接,用数 量来解决质量的问题。 但这种方式也存在缺陷。如果每个客户端都想自己快,建立很多个连接,用户数 × 并发数就会是个天文数 字。服务器的资源根本就扛不住,或者被服务器认为是恶意攻击,反而会造成“拒绝服务”。 所以,HTTP 协议建议客户端使用并发,但不能“滥用”并发。RFC2616 里明确限制每个客户端最多并发 2 个 连接。不过实践证明这个数字实在是太小了,众多浏览器都“无视”标准,把这个上限提高到了 6~8。后来 修订的 RFC7230 也就“顺水推舟”,取消了这个“2”的限制。 但“并发连接”所压榨出的性能也跟不上高速发展的互联网无止境的需求,还有什么别的办法吗? 公司发展的太快了,员工越来越多,上下班打卡成了迫在眉睫的大问题。前台空间有限,放不下更多的打卡 机了,怎么办?那就多开几个打卡的地方,每个楼层、办公区的入口也放上三四台打卡机,把人进一步分 流,不要都往前台挤。 这个就是“域名分片”(domain sharding)技术,还是用数量来解决质量的思路。 HTTP 协议和浏览器不是限制并发连接数量吗?好,那我就多开几个域名,比如 shard1.chrono.com、 shard2.chrono.com,而这些域名都指向同一台服务器 www.chrono.com,这样实际长连接的数量就又上去 了
← Cookie机制及HTTP缓存 XSS攻击 →