本文转载自HTTP 协议中的并发限制及队首阻塞问题

串行连接

HTTP/0.9 和早期的 HTTP/1.0 协议对 HTTP 请求处理是串行化的。假如一个页面包含 3 个样式文件,同属于一个协议、域名、端口。那么,浏览器一共需要发起四次请求,并且每次只能打开一个 TCP 通道,在一个请求资源完成下载后,立刻断开该连接,再开启一个新的连接去处理队列中的下一个请求。随着页面资源大小、数量的不断扩增,网络延迟时间会不断堆积,用户会面对满屏空白,等待过长时间而失去耐心。

并行连接

为了提高网络的吞吐能力,改进后的 HTTP 协议允许客户端同时打开多个 TCP 连接,并行地请求多个资源,充分利用带宽。通常,每一个连接之间都会有一定延迟,但请求的传输时间是重叠的,总体上时延要比串行连接低很多。考虑到每一个连接都会消耗系统资源,并且服务器需要处理海量的用户并发请求,浏览器会对并发请求数量做一定的限制。即使 RFC 并没有规定具体的限制数量,各浏览器厂商也都会有自己的标准:

  • IE 7: 2
  • IE 8/9: 6
  • IE 10: 8
  • IE 11: 13
  • Firefox: 6
  • Chrome: 6
  • Safari: 6
  • Opera: 6
  • iOS WebView: 6
  • Android WebView: 6

持久连接(长连接)

早期的 HTTP 协议对每个请求都占用一个独立的 TCP 连接,这无疑增加了 TCP 的建立连接开销、拥塞控制开销、释放连接开销,改进后的 HTTP/1.0 和 HTTP/1.1(默认)都支持了持久连接。如果一个请求完成后,不会立刻断开连接,而是在一定的时间内保持连接,以便快速处理即将到来的 HTTP 请求,复用同一个 TCP 通道,直到客户端心跳检测失败或服务器连接超时。这个特性可以通过 HTTP 首部 Connection: keep-alive 来激活,客户端也可以发送 Connection: close 来主动关闭连接。所以,我们看到,并行连接和持久连接这两种优化是相辅相成的,并行连接使得首次加载页面可以同时打开多个 TCP 连接,而持久连接保证了后续的请求复用已打开的 TCP 连接,这也是现代 Web 页面的普遍机制。

管道化连接

持久连接让我们可以重用连接来完成多次请求,但它必须满足 FIFO 的队列顺序,必须保证前一个请求成功到达服务器、处理成功并且收到服务器返回的首个字节,才可以发起队列中下一个请求。HTTP 管道允许客户端在同一个 TCP 通道内连续发起多个请求,而不必等待响应,消除了往返延迟时间差。但现实情况由于 HTTP/1.x 协议的限制,不允许数据在一个链路上交错到达(IO 多路复用)。设想一种情况,客户端服务器端同时发送一个 HTML 和多个 CSS 请求,服务器并行处理所有请求,当所有的 CSS 请求处理完成并加入到缓冲队列,却发现 HTML 请求处理遇到问题而无限被挂起,严重时甚至造成缓冲区溢出,这种情况就叫做队首阻塞。因此,这个方案在 HTTP/1.x 协议中并没有被采纳。

队首阻塞并不是 HTTP 中独有的概念,而是在缓存式通信网络交换中的一种普遍现象

总结

  1. 对于同一个协议、域名、端口,浏览器允许同时打开个 TCP 连接,一般上限为 6 个。
  2. 同一个 TCP 连接允许发起多次 HTTP 请求,但必须等待前一个请求的首个字节响应到达客户端。
  3. 由于队首阻塞问题,不允许客户端同时发送队列中所有请求,这个问题在 HTTP/2.0 得已解决。

最新文章

  1. Atitit.数据检索与网络爬虫与数据采集的原理概论
  2. 夺命雷公狗---TP商城----TP之样式和特效以及图片引入---2
  3. 理解 Android Build 系统
  4. mysql 内连接 左连接 右连接 外连接
  5. 2016- 1- 16 NSThread 的学习
  6. Error: Cannot find module 'express'
  7. 【转】mac终端安装node时候,显示“-bash: brew: command not found”,怎么解决?
  8. [转] android自动化测试之MonkeyRunner使用实例(三)
  9. [状压dp]经典TSP
  10. 【二分】XMU 1587 中位数
  11. ARM Cortex-M3内核的巨大优势
  12. JVM基础02-class文件
  13. xmake v2.1.5版本正式发布,大量新特性更新
  14. form表单action=""的作用
  15. 监控undo空间和临时段的使用情况
  16. 你真的了解webview么?
  17. 洛谷P3379 【模板】最近公共祖先(LCA)(树链剖分)
  18. centos 7 安装 MySQL 5.6
  19. node.js小案例_留言板
  20. Python socket实现处理多个连接

热门文章

  1. Web漏洞扫描-AppScan
  2. JavaScript——DOM操作
  3. Java——反射机制
  4. Docker --volume(数据持久化)
  5. OSPF路由汇总
  6. 图的广度优先遍历算法(BFS)
  7. Maven多模块的2种依赖管理策略
  8. SOLID:面向对象设计的五个基本原则
  9. HDU-6148 Valley Number (数位DP)
  10. Educational Codeforces Round 84 (Div. 2)