本文转载自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 得已解决。

HTTP 协议中的并发限制及队首阻塞问题的更多相关文章

  1. 【http】http协议的队首阻塞

    1 队首阻塞 就是需要排队,队首的事情没有处理完的时候,后面的人都要等着. 2 http1.0的队首阻塞 对于同一个tcp连接,所有的http1.0请求放入队列中,只有前一个请求的响应收到了,然后才能 ...

  2. http协议的队首阻塞

    1 队首阻塞 就是需要排队,队首的事情没有处理完的时候,后面的人都要等着. 2 http1.0的队首阻塞 对于同一个tcp连接,所有的http1.0请求放入队列中,只有前一个请求的响应收到了,然后才能 ...

  3. 从TCP三次握手说起–浅析TCP协议中的疑难杂症(2)

    版权声明:本文由黄日成原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/108 来源:腾云阁 https://www.qclo ...

  4. Java中多线程并发体系知识点汇总

    一.多线程 1.操作系统有两个容易混淆的概念,进程和线程. 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进程的地址空间是互相隔离的:进程拥有各种 ...

  5. Go中的并发编程和goroutine

    并发编程对于任何语言来说都不是一件简单的事情.Go在设计之初主打高并发,为使用者提供了goroutine,使用的方式虽然简单,但是用好却不是那么容易,我们一起来学习Go中的并发编程. 1. 并行和并发 ...

  6. C#中实现并发的几种方法的性能测试

    C#中实现并发的几种方法的性能测试 0x00 起因 去年写的一个程序因为需要在局域网发送消息支持一些命令和简单数据的传输,所以写了一个C/S的通信模块.当时的做法很简单,服务端等待链接,有用户接入后开 ...

  7. PBOC协议中对于所有电子存折/电子钱包应用的预处理

    下图给出了PBOC协议中规定的对电子存折/电子钱包应用的所有交易类型共有的预处理流程 图1 1.1 插入卡片 终端应具有检测IC卡是否已经插入读卡器的功能.如果IC卡已经插入,终端将继续执行1.2的应 ...

  8. http协议中用于上传多个文件的 multipart 字段

    大家好,我是许飞,微软拼音的开发实习生.在网络编程中,经常用到从服务器上“下载”一些数据,有时却要向服务器“上传”数据.曾在一个原型中使用了“multipart/form-data”格式向Web服务器 ...

  9. C#的HTTP协议中POST与GET的区别

    引言 HTTP协议我想任何IT人士都耳熟能详了,大家都能说出个所以然来.但是如果我问你HTTP协议的请求方法有哪些?POST与GET的差异?GET或POST传送数据量的大小有限制吗?HTTP响应的状态 ...

随机推荐

  1. linux 系统磁盘管理(主分区和逻辑分区)

    摘要:linux系统磁盘管理主分区和逻辑分区 1.linux系统分区应了解的常识 硬盘分区实质上是对硬盘的一种格式化,然后才能使用硬盘保存各种信息,在创建分区时,就已经设置好了硬盘的各项物理参数,指定 ...

  2. CCF-有趣的数(数位DP)

    有趣的数   问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次. 2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前 ...

  3. Rsync同步工具

    1.Rsync介绍 1.1 什么是Rsync? Rsync,remote synchronize顾名思意就知道它是一款实现远程同步功能的软件,它在同步文件的同时,可以保持原来文件的权限.时间.软硬链接 ...

  4. 通过HBase Observer同步数据到ElasticSearch

    Observer希望解决的问题 HBase是一个分布式的存储体系,数据按照RowKey分成不同的Region,再分配给RegionServer管理.但是RegionServer只承担了存储的功能,如果 ...

  5. left join与inner join

    举例a.b表: bId bNum 1 20 2 30 aId aNum 1 10 2 20 3 30 left join以左表为准 select * from a left join b on a.a ...

  6. 洛谷 P1429 平面最近点对(加强版) (分治模板题)

    题意:有\(n\)个点对,找到它们之间的最短距离. 题解:我们先对所有点对以\(x\)的大小进行排序,然后分治,每次左右二等分递归下去,当\(l+1=r\)的时候,我们计算一下距离直接返回给上一层,若 ...

  7. 【ybt高效进阶2-4-3】【luogu P4551】最长异或路径

    最长异或路径 题目链接:ybt高效进阶2-4-3 / luogu P4551 题目大意 给定一棵 n 个点的带权树,结点下标从 1 开始到 N.寻找树中找两个结点,求最长的异或路径. 异或路径指的是指 ...

  8. Shell 编程练习

    将后缀名为 .txt 的文件改成 .log [root@k8s-master test]# touch localhost_2020-01-{02..26}.txt [root@k8s-master ...

  9. Python源码剖析——02虚拟机

    <Python源码剖析>笔记 第七章:编译结果 1.大概过程 运行一个Python程序会经历以下几个步骤: 由解释器对源文件(.py)进行编译,得到字节码(.pyc文件) 然后由虚拟机按照 ...

  10. C++ STL (基础)

    STL是什么(STL简介) 本节主要讲述 STL 历史.STL 组件.STL 基本结构以及 STL 编程概述.STL 历史可以追溯到 1972 年 C 语言在 UNIX 计算机上的首次使用.直到 19 ...