Bootstrap

HTTP3原理解析和实战应用

http协议原理解析

HTTP1.1改动

keeplive

在http1.0版本中http连接会在每次请求都会发起连接, 并且每次连接在保证安全性都需要建立三次握手, 每次请求后就立即断开连接, 下次请求就还需要重新建立连接.这样就提升了请求的复杂度.

keeplive就使得每次建立连接后可以多次请求.

pipelining

改动点就是串行请求改为支持并发请求, 具体可以并发多少个连接是由浏览器决定, 一般情况下最多并发6个连接, 可以一定程度节省时间, 但是会占用一定的资源.

HTTP2.0改动

二进制帧

1.1每一行有对应的明确信息, 表示分别是什么数据. 到2.0时对应的请求是发送的二进制帧数据(二进制帧还可以进行压缩).

一个连接可以理解为一个通道, 流就是在这个这个通道上划分的车道, 数据包就是通行的车辆, 在不同的车道上可以并行的通过一个通道传输.通过streamid进行区分.

流可以粗略的理解成一个请求, 多个请求可以同时在一个连接上进行发送.

流优先级、流依赖问题

有些业务为什么从HTTP1.1更新到HTTP2.0之后反而变慢了?

流优先级: 比如请求一个网站需要发同时100个请求, 服务端会有一个优先级的过程, 流的优先级是业务层定义的. 如果业务层定义的不是很合理, 那么就会导致有些资源会一直在blocking的状态. 只有在处理好优先级更高的资源之后才会处理优先级低的. 优先级低的一直那不到回应就会等的时间很长.

流依赖: 一条流会依赖另外一条流, 比如请求1拿到资源, 但是必须依赖请求0拿到资源之后才能进行处理, 如果依赖的资源很慢那么当前流的处理就也会很慢.

队头阻塞问题

TCP有一个特点, 必须保证有序性.

如果Request1的数据先发送Request2后发送, 但是Request1中的包有丢失的, Request2包已经达到了客户端, 这时也不能交付给上层业务, 只有等丢失的包重传之后才会交付给上层业务.

所以HTTP2中一个流的包丢了会影响一个连接中所有流的数据包.

适合哪些场景

  • 使用服务器推送数据
  • 网路质量好, 丢包率低的场景
  • 并发量比较大, 小资源比较多
  • 有明显的优先级或互相依赖的请求(如果优先级不明确不好界定, 那么可能效果达不到很好的效果)

HTTP3.0

HTTP/2和HTTP/3对比

从HTTP2.0中的请求流程可以看出, 为了一个1RTT的请求数据前面需要建立1个DNS+4RTT的流程才能拿到相应.

HTTP2.0 和 HTTP3.0 协议对比

实际上就是在UDP的基础上将TCP的可靠性和TLS1.3融合进来实现QUIC协议, QUIC协议是在用户态. QUIC虽然实现是在用户态, 但是还是认为QUIC协议是一个传输层协议, 因为它的功能主要还是在传输数据.

HTTP3.0才是应用层的协议.

HTTP/3的核心在于QUIC协议

事实上, 我们并不是真的需要新的HTTP版本, 而是需要对底层的传输协议(TCP)进行升级.

quic协议原理

此处为语雀内容卡片,点击链接查看:https://www.yuque.com/yyqcy/rmskr5/mlfnzath422xlkmo

0RTT握手

连接迁移

更优秀的拥塞控制算法

quic中丢包重传包的序号是单调递增的, 而TCP中的丢包重传包序号是不变的.

TCP中因为包序号是不变的, 那么重传的包和延时的包都收到后, 就不知道哪一个是开始的包, 不知道哪一个是后来的, 这样就会出现重传包的二义性. 重传包的二义性直接导致RTT计算不准确.从而影响拥塞控制算法.

两级流量控制

QUIC的滑动窗口的大小仅仅由可用窗口来决定, 不会受到丢包的影响. 只要可用窗口还有就能够发数据和接收数据.

协议竞速

业内统计数据全球有7%地区的运营商对UDP有限速或者禁闭,除了运营商还有很多企业、公共场合也会限制UDP流量甚至禁用UDP。这对使用UDP来承载QUIC协议的场景会带来致命的伤害。

对此,可以采用多路竞速的方式使用TCP和QUIC同时建连。除了在建连进行竞速以外,还可以对网络QUIC和TCP的传输延吋进行实时监控和对比,如果有链路对UDP进行了限速,可以动态从QUIC切换到TCP

性能效果

通过弱网实验测试,QUIC在开启O-RTT时,其延迟要比HTTP降低20%,比HTTPS要降低50%以上。

应用场景

  • 连接复用率低: 连接迁移的场景
  • 小文件下载场景
  • RTT比较长, 丢包率较高(弱网环境)
  • 必须要加密传输
  • 非特别敏感业务(UDP安全性可能存在问题)
  • 连接迁移强需求(语音业务: 语音助手)

代码实现

;