通信技术|从起源到发展 详说HTTP从1到3的演变( 五 )
- Reduce connection establishment latency (减少连接建立时间)
- Improved congestion control (改进拥塞控制)
- Multiplexing without head-of-line blocking (没有队头阻塞的多路复用)
- Forward error correction (修复之前的错误)
- Connection migration(支持网络迁移)
这句话说起来很容易,但理解起来并不那么显然,要想理解 QUIC 协议到底做了什么以及这么做的必要性,我想还是从最基础的 HTTP/1.0 聊起比较合适 。
Pipiline
根据谷歌的调查,现在请求一个网页,平均涉及到 80 个资源,30 多个域名 。考虑最原始的情况,每请求一个资源都需要建立一次 TCP 请求,显然不可接受 。HTTP 协议规定了一个字段 Connection,不过默认的值是 close,也就是不开启 。
早在 1999 年提出的 HTTP 1.1 [https://www.ietf.org/rfc/rfc2616.txt] 协议 中就把 Connection 的默认值改成了Keep-Alive,这样同一个域名下的多个 HTTP 请求就可以复用同一个 TCP 连接 。这种做法被称为 HTTP Pipeline,优点是显著的减少了建立连接的次数,也就是大幅度减少了 RTT 。
以上面的数据为例,如果 80 个资源都要走一次 HTTP 1.0,那么需要建立 80 个 TCP 连接,握手 80 次,也就是 80 个 RTT 。如果采用了 HTTP 1.1 的 Pipeline,只需要建立 30 个 TCP 连接,也就是 30 个 RTT,提高了 62.5% 的效率 。
Pipeline 解决了 TCP 连接浪费的问题,但它自己还存在一些不足之处,也就是所有管道模型都难以避免的队头阻塞问题 。
队头阻塞
我们再举个简单而且直观的例子,假设加载一个 HTML 一共要请求 10 个资源,那么请求的总时间是每一个资源请求时间的总和 。最直观的体验就是,网速越快请求时间越短 。然而如果某一个资源的请求被阻塞了(比如 SQL 语句执行非常慢) 。但对于客户端来说所有后续的请求都会因此而被阻塞 。
文章图片
队头阻塞(Head of line blocking,下文简称 HOC)说的是当有多个串行请求执行时,如果第一个请求不执行完,后续的请求也无法执行 。比如上图中,如果第四个资源的传输花了很久,后面的资源都得等着,平白浪费了很多时间,带宽资源没有得到充分利用 。
因此,HTTP 协议允许客户端发起多个并行请求,比如在笔者的机器上最多支持六个并发请求 。并发请求主要是用于解决 HOC 问题,当有三个并发请求时,情况会变成这样:
文章图片
可见虽然第四个资源的请求被阻塞了,但是其他的资源请求并不一定会被阻塞,这样总的来说网络的平均利用率得到了提升 。
支持并发请求是解决 HOC 问题的一种方案,这句话没有错 。但是我们要理解到:“并发请求并非是直接解决了 HOC 的问题,而是尽可能减少 HOC 造成的影响“,以上图为例,HOC 的问题依然存在,只是不会太浪费带宽而已 。
有读者可能会好奇,为什么不多搞几个并发的 HTTP 请求呢?刚刚说过笔者的电脑最多支持 6 个并发请求,谷歌曾经做过实验,把 6 改成 10,然后尝试访问了三千多个网页,发现平均访问时间竟然还增加了 5% 左右 。这是因为一次请求涉及的域名有限,再多的并发 HTTP 请求并不能显著提高带宽利用率,反而会消耗性能 。
SPDY 的做法
有没有办法解决队头阻塞呢?
答案是肯定的 。SPDY 协议的做法很值得借鉴,它采用了多路复用(Multiplexing)技术,允许多个 HTTP 请求共享同一个 TCP 连接 。我们假设每个资源被分为多个包传递,在 HTTP 1.1 中只有前面一个资源的所有数据包传输完毕后,后面资源的包才能开始传递(HOC 问题),而 SPDY 并不这么要求,大家可以一起传输 。
这么做的代价是数据会略微有一些冗余,每一个资源的数据包都要带上标记,用来指明自己属于哪个资源,这样客户端最后才能把他们正确的拼接起来 。不同的标记可以理解为图中不同的颜色,每一个小方格可以理解为资源的某一个包 。
TCP 窗口
是不是觉得 SPDY 的多路复用已经够厉害了,解决了队头阻塞问题?很遗憾的是,并没有,而且我可以很肯定的说,只要你还在用 TCP 链接,HOC 就是逃不掉的噩梦,不信我们来看看 TCP 的实现细节 。
我们知道 TCP 协议会保证数据的可达性,如果发生了丢包或者错包,数据就会被重传 。于是问题来了,如果一个包丢了,那么后面的包就得停下来等这个包重新传输,也就是发生了队头阻塞 。当然 TCP 协议的设计者们也不傻,他们发明了滑动窗口的概念:
文章图片
这样的好处是在第一个数据包(1-1000) 发出后,不必等到 ACK 返回就可以立刻发送第二个数据包 。可以看出图中的 TCP 窗口大小是 4,所以第四个包发送后就会开始等待,直到第一个包的 ACK 返回 。这样窗口可以向后滑动一位,第五个包被发送 。
推荐阅读
- |潍坊新昌发展区:城市管理有妙招 用好诚信积分制
- 教育信息化|西藏:推动教育信息化发展建设“数字校园”
- 怀进鹏|怀进鹏:汇聚中小企业力量推动数字经济合作发展
- TikTok|海外发展受阻国内拓展新领域字节跳动的全球平衡术
- OLEDOLED面板出货量|2020年全球OLED市场发展现状和供需分析预测 全球OLED面板预期出货4.65亿片
- 可再生能源可再生能源发电|2020年全球可再生能源发展趋势投资前景 全球可再生能源发电规模放缓至6%
- 通信技术|印度首富宣布成功研发5G技术:献给莫迪“自力更生的印度”计划
- 农业|我国首次对乡村产业发展做出全面规划乡村产业,等你来
- 通信技术|国家统计局:上半年全国光缆产量1.32亿芯千米
- 聚乙烯塑料购物袋|2020年聚乙烯市场发展现状和前景 中国明年禁用不可降解塑料购物袋