看 B 站,可以更快!
现在用谷歌浏览器看 B 站视频,默认是用 HTTP/2 协议,它相比 HTTP/1.1 性能提高很多,但是其实看 B 站视频还能更快!
因为 B 站部分视频服务器支持使用 QUIC 协议观看视频,QUIC 是基于 UDP 传输协议实现的,而且最新的 HTTP/3 使用的正是 QUIC 协议,它相比 HTTP/2 性能其实更好,观看视频体验更佳,特别是弱网环境下。
QUIC 协议性能有多好?
Chromium ( Google 的 Chrome 浏览器背后的引擎)团队表示,其发现 QUIC 的性能优势特别高,使得 Google 搜索延迟减少了 2% 以上,YouTube 的重新缓冲时间减少了 9% 以上,PC 客户端吞吐量增加了 3% 以上,移动设备的客户端吞吐量增加了 7% 以上。
怎么用 QUIC 看 B 站视频?
手机端我没研究过怎么使用 QUIC 协议看 B 站视频,但是谷歌浏览器则很容易搞定。
谷歌浏览器支持 QUIC 协议,这个是属于实验性功能,QUIC 协议实际上还在草案中,还没有正式发布,所以不是默认启动的,需要手动打开。
第一步,打开Chrome浏览器, 在地址输入 chrome://flags/#enable-quic
, 将标志设置为 Enabled
。
第二步,重启浏览器后, 打开B站, 随便点开个视频,然后检查是否使用 QUIC 协议进行视频播放, 检查方法如下:
按下
F12
进入浏览器调试信息界面;选取 Network->Protocol, 如果 Protocol 显示 h3 则表示目前是使用 HTTP/3 (意味着使用 QUIC 协议)协议进行视频内容传输。
比如下图,我在看何同学采访库克的B站视频,使用了 HTTP3 协议:
注意:如果打开后,你访问速度受影响而变慢了,那么你记得要关闭掉这个功能,因为 QUIC 协议使用的传输协议是 UDP,有些运营商的网络在繁忙的时候,会把 UDP 包给丢掉。
转场
好了,B 站的事情就介绍到这了,你以为这次我要聊 B 站,其实我要聊的是 HTTP/3 !
真不容易呀,小林为了让大家学习 HTTP/3,煞费苦心布置了 B 站这个幌子,吸引大家点进来。所以,大家不要觉得是标题党哈。
事实上,HTTP/3 现在还没正式推出,不过自 2017 年起, HTTP/3 已经更新到 34 个草案了,基本的特性已经确定下来了,对于包格式可能后续会有变化。
所以,这次 HTTP/3 介绍不会涉及到包格式,只说它的特性。
美中不足的 HTTP/2
HTTP/2 通过头部压缩、二进制编码、多路复用、服务器推送等新特性大幅度提升了 HTTP/1.1 的性能,而美中不足的是 HTTP/2 协议是基于 TCP 实现的,于是存在的缺陷有三个。
队头阻塞;
TCP 与 TLS 的握手时延迟;
网络迁移需要重新连接;
队头阻塞
HTTP/2 多个请求是跑在一个 TCP 连接中的,那么当 TCP 丢包时,整个 TCP 都要等待重传,那么就会阻塞该 TCP 连接中的所有请求。
因为 TCP 是字节流协议,TCP 层必须保证收到的字节数据是完整且有序的,如果序列号较低的 TCP 段在网络传输中丢失了,即使序列号较高的 TCP 段已经被接收了,应用层也无法从内核中读取到这部分数据,从 HTTP 视角看,就是请求被阻塞了。
举个例子,如下图:
图中发送方发送了很多个 packet,每个 packet 都有自己的序号,你可以认为是 TCP 的序列号,其中 packet 3 在网络中丢失了,即使 packet 4-6 被接收方收到后,由于内核中的 TCP 数据不是连续的,于是接收方的应用层就无法从内核中读取到,只有等到 packet 3 重传后,接收方的应用层才可以从内核中读取到数据,这就是 HTTP/2 的队头阻塞问题,是在 TCP 层面发生的。
TCP 与 TLS 的握手时延迟
发起 HTTP 请求时,需要经过 TCP 三次握手和 TLS 四次握手(TLS 1.2)的过程,因此共需要 3 个 RTT 的时延才能发出请求数据。
另外, TCP 由于具有「拥塞控制」的特性,所以刚建立连接的 TCP 会有个「慢启动」的过程,它会对 TCP 连接产生"减速"效果。
网络迁移需要重新连接
一个 TCP 连接是由四元组(源 IP 地址,源端口,目标 IP 地址,目标端口)确定的,这意味着如果 IP 地址或者端口变动了,就会导致需要 TCP 与 TLS 重新握手,这不利于移动设备切换网络的场景,比如 4G 网络环境切换成 WIFI。
这些问题都是 TCP 协议固有的问题,无论应用层的 HTTP/2 在怎么设计都无法逃脱。
要解决这个问题,就必须把传输层协议替换成 UDP,这个大胆的决定,HTTP/3 做了!
QUIC 协议的特点
我们深知,UDP 是一个简单、不可靠的传输协议,而且是 UDP 包之间是无序的,也没有依赖关系。
而且,UDP 是不需要连接的,也就不需要握手和挥手的过程,所以天然的就比 TCP 快。
当然,HTTP/3 不仅仅只是简单将传输协议替换成了 UDP,还基于 UDP 协议在「应用层」实现了 QUIC 协议,它具有类似 TCP 的连接管理、拥塞窗口、流量控制的网络特性,相当于将不可靠传输的 UDP 协议变成“可靠”的了,所以不用担心数据包丢失的问题。
QUIC 协议的优点有很多,这里举例几个,比如:
无队头阻塞;
更快的连接建立;
连接迁移;
无队头阻塞
QUIC 协议也有类似 HTTP/2 Stream 与多路复用的概念,也是可以在同一条连接上并发传输多个 Stream,Stream 可以认为就是一条 HTTP 请求。
由于 QUIC 使用的传输协议是 UDP,UDP 不关心数据包的顺序,如果数据包丢失,UDP 也不关心。不过,QUIC 协议会保证数据包的可靠性,每个数据包都有一个序号唯一标识。
如果 QUIC 连接中的某个流中的一个数据包丢失了,只会阻塞该流,其他流不会受影响。这与 HTTP/2 不同,HTTP/2 只要某个流中的数据包丢失了,其他流也会因此受影响。
所以,QUIC 连接上的多个 Stream 之间并没有依赖,都是独立的,某个流发生丢包了,只会影响该流,其他流不受影响,消除了 HTTP/2 的队头阻塞问题。
更快的连接建立
对于 HTTP/1 和 HTTP/2 协议,TCP 和 TLS 是分层的,分别属于内核实现的传输层、openssl 库实现的表示层,因此它们难以合并在一起,需要分批次来握手,先 TCP 握手,再 TLS 握手。
HTTP/3 在传输数据前虽然需要 QUIC 协议握手,这个握手过程只需要 1 RTT,握手的目的是为确认双方的「连接 ID」,连接迁移就是基于连接 ID 实现的。
但是 HTTP/3 的 QUIC 协议并不是与 TLS 分层,而是QUIC 内部包含了 TLS,它在自己的帧会携带 TLS 里的“记录”,再加上 QUIC 使用的是 TLS1.3,因此仅需 1 个 RTT 就可以「同时」完成建立连接与密钥协商,甚至在第二次连接的时候,应用数据包可以和 QUIC 握手信息(连接信息 + TLS 信息)一起发送,达到 0-RTT 的效果。
如下图右边部分,HTTP/3 当会话恢复时,有效负载数据与第一个数据包一起发送,可以做到 0-RTT:
连接迁移
在前面我们提到,基于 TCP 传输协议的 HTTP 协议,由于是通过四元组(源 IP、源端口、目的 IP、目的端口)确定一条 TCP 连接。
那么当移动设备的网络从 4G 切换到 WIFI 时,意味着 IP 地址变化了,就必须要断开连接,然后重新建立连接,而建立连接的过程包含 TCP 三次握手和 TLS 四次握手的时延,以及 TCP 慢启动的减速过程,给用户的感觉就是网络突然卡顿了一下,因此连接的迁移成本是很高的。
而 QUIC 协议没有用四元组的方式来“绑定”连接,而是通过连接 ID来标记通信的两个端点,客户端和服务器可以各自选择一组 ID 来标记自己。
因此,即使移动设备的网络变化后,导致 IP 地址变化了,只要仍保有上下文信息(比如连接 ID、TLS 密钥等),就可以“无缝”地复用原连接,消除重连的成本,没有丝毫卡顿感,达到了连接迁移的功能。
HTTP/3 协议
了解完 QUIC 协议的特点后,我们再来看看 HTTP/3 协议在 HTTP 这一层做了什么变化。
HTTP/3 同 HTTP/2 一样采用二进制帧的结构,不同的地方在于 HTTP/2 的二进制帧里需要定义 Stream,而 HTTP/3 自身不需要再定义 Stream,直接使用 QUIC 里的 Stream,于是 HTTP/3 的帧的结构也变简单了。
从上图可以看到,HTTP/3 帧头只有两个字段:类型和长度。
根据帧类型的不同,大体上分为数据帧和控制帧两大类,HEADERS 帧(HTTP 头部)和 DATA 帧(HTTP 包体)属于数据帧。
HTTP/3 在头部压缩算法这一方便也做了升级,升级成了 QPACK。与 HTTP/2 中的 HPACK 编码方式相似,HTTP/3 中的 QPACK 也采用了静态表、动态表及 Huffman 编码。
对于静态表的变化,HTTP/2 中的 HPACK 的静态表只有 61 项,而 HTTP/3 中的 QPACK 的静态表扩大到 91 项。
HTTP/2 和 HTTP/3 的 Huffman 编码并没有多大不同,但是动态表编解码方式不同。
所谓的动态表,在首次请求-响应后,双方会将未包含在静态表中的 Header 项更新各自的动态表,接着后续传输时仅用 1 个数字表示,然后对方可以根据这 1 个数字从动态表查到对应的数据,就不必每次都传输长长的数据,大大提升了编码效率。
可以看到,动态表是具有时序性的,如果首次出现的请求发生了丢包,后续的收到请求,对方就无法解码出 HPACK 头部,因为对方还没建立好动态表,因此后续的请求解码会阻塞到首次请求中丢失的数据包重传过来。
HTTP/3 的 QPACK 解决了这一问题,那它是如何解决的呢?
QUIC 会有两个特殊的单向流,所谓的单项流只有一端可以发送消息,双向则指两端都可以发送消息,传输 HTTP 消息时用的是双向流,这两个单向流的用法:
一个叫 QPACK Encoder Stream, 用于将一个字典(key-value)传递给对方,比如面对不属于静态表的 HTTP 请求头部,客户端可以通过这个 Stream 发送字典;
一个叫 QPACK Decoder Stream,用于响应对方,告诉它刚发的字典已经更新到自己的本地动态表了,后续就可以使用这个字典来编码了。
这两个特殊的单向流是用来同步双方的动态表,编码方收到解码方更新确认的通知后,才使用动态表编码 HTTP 头部。
总结
HTTP/2 虽然具有多个流并发传输的能力,但是传输层是 TCP 协议,于是存在以下缺陷:
队头阻塞,HTTP/2 多个请求跑在一个 TCP 连接中,如果序列号较低的 TCP 段在网络传输中丢失了,即使序列号较高的 TCP 段已经被接收了,应用层也无法从内核中读取到这部分数据,从 HTTP 视角看,就是多个请求被阻塞了;
TCP 和 TLS 握手时延,TCL 三次握手和 TLS 四次握手,共有 3-RTT 的时延;
连接迁移需要重新连接,移动设备从 4G 网络环境切换到 WIFI 时,由于 TCP 是基于四元组来确认一条 TCP 连接的,那么网络环境变化后,就会导致 IP 地址或端口变化,于是 TCP 只能断开连接,然后再重新建立连接,切换网络环境的成本高;
HTTP/3 就将传输层从 TCP 替换成了 UDP,并在 UDP 协议上开发了 QUIC 协议,来保证数据的可靠传输。
QUIC 协议的特点:
无队头阻塞,QUIC 连接上的多个 Stream 之间并没有依赖,都是独立的,也不会有底层协议限制,某个流发生丢包了,只会影响该流,其他流不受影响;
建立连接速度快,因为 QUIC 内部包含 TLS1.3,因此仅需 1 个 RTT 就可以「同时」完成建立连接与 TLS 密钥协商,甚至在第二次连接的时候,应用数据包可以和 QUIC 握手信息(连接信息 + TLS 信息)一起发送,达到 0-RTT 的效果。
连接迁移,QUIC 协议没有用四元组的方式来“绑定”连接,而是通过连接 ID 来标记通信的两个端点,客户端和服务器可以各自选择一组 ID 来标记自己,因此即使移动设备的网络变化后,导致 IP 地址变化了,只要仍保有上下文信息(比如连接 ID、TLS 密钥等),就可以“无缝”地复用原连接,消除重连的成本;
另外 HTTP/3 的 QPACK 通过两个特殊的单向流来同步双方的动态表,解决了 HTTP/2 的 HPACK 队头阻塞问题。
不过,由于 QUIC 使用的是 UDP 传输协议,UDP 属于“二等公民”,大部分路由器在网络繁忙的时候,会丢掉 UDP包,把“空间”让给 TCP 包,所以 QUIC 的推广之路应该没那么简单。
期待,HTTP/3 正式推出的那一天!
参考连接
https://medium.com/faun/http-2-spdy-and-http-3-quic-bae7d9a3d484
https://developers.google.com/web/fundamentals/performance/http2?hl=zh-cn
https://blog.cloudflare.com/http3-the-past-present-and-future/
https://tools.ietf.org/html/draft-ietf-quic-http-34
https://tools.ietf.org/html/draft-ietf-quic-transport-34#p-17
https://ably.com/topic/http3?amp%3Butm_campaign=evergreen&%3Butm_source=reddit&utm_medium=referral
https://www.nginx.org.cn/article/detail/422
https://www.bilibili.com/read/cv793000/
https://www.chinaz.com/2020/1009/1192436.shtml
有道无术,术可成;有术无道,止于术
欢迎大家关注Java之道公众号
好文章,我在看❤️
看 B 站,可以更快!相关推荐
- 公司网络推广分享新站如何更快的获得首页排名的技巧!
网站在上线后,很多公司网络推广优化人员们都是很迫不及待的希望自己的网站能够更早的出现在搜索引擎的首页,这样才能帮助网站带来更多的流量和权重,那么对于新站该做好哪些优化才能更快的获得百度首页位置的排名呢 ...
- 使Gradle构建更快 2016年2月5日奥列格Shelajev3评论 推特 inShare 70 上次我们谈到了构建系统,我们看着一些建议可能会使您的Maven构建更快。我们得到的结果是迷人的和对
使Gradle构建更快 2016年2月5日 奥列格Shelajev 3评论 推特 inShare70 上次我们谈到了构建系统,我们看着一些建议可能会使您的Maven构建更快.我们得到的结果是迷人的和对 ...
- 【转】实战USB接口手机充电 看3.0/2.0谁更快
原文网址:http://mb.it168.com/a2012/0816/1385/000001385641_all.shtml [IT168 应用]当下,越来越多的电脑都已普及USB 3.0接口,新买 ...
- 刘润:五维思考,让你站得更高、看得更远
原标题:刘润:五维思考,让你站得更高.看得更远 前言:遇到问题时,有的人很快就能想明白,有的人需要很久才能想明白,还有的人始终都想不明白. 而且,那些很快就能想明白的人,发现不管自己怎么努力,都很难帮 ...
- 四川网络推广浅析新站要如何更快的获得好排名?
四川网络推广表示网站在上线之后,都想让网站能快速的获得好排名,提升网站的影响力,来为企业带来更多的用户和流量等,但想要新站快速的获得排名也不是件容易的事,那么怎样花较短时间去完成呢?下面就由四川网络推 ...
- 神策数据:从技术视角看,如何更多、更好、更快地实施A/B试验
A/B 测试被更多人熟知的是持续观察并对照按一定规则分成的 A.B 两组测试样本,基于数据反馈辅助优化决策,其背后复杂的数学理论和试验基础设施却往往被人忽视. 目前,国内一线互联网公司大多采用自研的方 ...
- wifi分析仪怎么看哪个信道好_无线路由器选择哪个信道上网更快以获得最佳WIFI体验...
本帖最后由 qq6199380 于 2015-3-19 13:54 编辑 如果你对家中无线路由器的设置过程有所了解,那么你一定曾经见到过"信道"这个词.其实大多数无线路由器的信道都 ...
- 自动驾驶年度激辩:载货比载人更快,商业化应成为评价指标 | MEET2021
编辑部 整理自 MEET 2021 量子位 报道 | 公众号 QbitAI "载人场景下,国内公开道路Robobus一定比Robotaxi更快落地." "关于运人和运货, ...
- 【转】新思想、新技术、新架构——更好更快的开发现代ASP.NET应用程序(续1)
上周星期天开通了博客并发布了第一篇文章<新思想.新技术.新架构--更好更快的开发现代ASP.NET应用程序>,汇集了一些比较流行的技术和开源项目,也把自己的程序架构.部分代码风格.前端表现 ...
最新文章
- 一个数里有那些约数用c++怎么做_嵌入式就业的那些事~
- 动手动脑(继承与多态)
- 1001.害死人不偿命的(3n+1)猜想
- FLV视频在IIS6.0下不能播放 处理的方法
- 史上最清楚的BP算法详解
- 简历上终于可以写“精通MySQL”!
- 网络七大趋势 媒介将很快彻底消失
- python动态创建字典_如何在Python中创建动态命名字典?
- 一汽奔腾b7o价位_全新奔腾B70正式上市,前脸被吐槽酷似某豪华品牌
- win7下cmd常用命令
- Java线程状态与方法关系
- Java扫码登录原理
- firewalld防火墙配置、测试服务、高级配置与IP伪装、端口转发
- android 如何从 3.55mm耳机接口 读取数据,USB Type-C接口详细定义,自制Type-C转3.5mm耳机转接线...
- 图解IFRS9 金融工具(8)减值准备规则比较
- 生成MT/MTd模式的tet.lib
- 项目管理工具——项目开发者工具
- 2019年最新最全香港5大银行开户条件及攻略
- IDEA类左侧有一个对勾,如何去掉对勾?
- 在5个月内从Carpenter到前端开发人员
热门文章
- mac docker安装linux,Mac上使用docker安装centos
- 广告roi怎么计算公式_二类电商信息流广告投放注意这几方面
- n条直线相交最多有几个邻补角_【初中数学】102条做初中几何辅导线的规律
- firefox使用掘金插件_久等了,这款知名浏览器下载插件终于上线Chrome版本!
- int指针初始化_C++:变量,指针,引用const,extern,using,typedef,decltype关键字
- c语言形式参数若为b 4,2016年计算机二级c语言题库
- Android 中opengl es灯光效果实例
- pycharm安装xlrd失败_Pycharm 下载与安装 详解
- coredump_filter的设置
- cache工作的详细过程