- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
我们前一篇学习了HTTP/2,相比于HTTP/1,HTTP/2在性能上有了大幅的改进,但是HTTP/2因为底层还是基于TCP协议的,虽然HTTP/2在应用层引入了流的概念,利用多路复用解决了队头阻塞的问题,但是在TCP中队头阻塞的问题仍旧存在.
又由于TCP协议的僵化、TCP的慢启动,为了确保连接建立而产生的延迟问题等顽固问题。HTTP/2虽然在性能上达到了极致,但是还是改变不了底层TCP的性能影响。毕竟应用层。得,死路一条。那怎么办呢?
既然不能用TCP,那就用UDP好啦。我们来看张图,把我们学过的协议的栈层都罗列一下,方便对比:
HTTPS的SSL和TLS我们在下一篇就开始聊,先不管。我们看HTTP/1、HTTPS、HTTP/2,和HTTP3在传输层有啥区别?HTTP/3用的是UDP。因为UDP是无序的,包与包之间没有依赖关系,就像HTTP/2的多路复用一样,从根本上解决了TCP的队头阻塞.
但是,你肯定知道,UDP是一个简单的,不可靠的协议,只是对IP协议的一层很薄的包装,和TCP相比,它的实际应用很少。不过正是因为它简单,不需要建连和断连,通信成本低,也就非常灵活、高效,“可塑性”很强.
所以,QUIC 就选定了 UDP,在它之上把 TCP 的那一套连接管理、拥塞窗口、流量控制等“搬”了过来,“去其糟粕,取其精华”,打造出了一个全新的可靠传输协议,可以认为是“新时代的 TCP”.
QUIC 最早是由 Google 发明的,被称为 gQUIC。而当前正在由 IETF 标准化的 QUIC 被称为 iQUIC。两者的差异非常大。gQUIC 混合了 UDP、TLS、HTTP,是一个应用层的协议。而 IETF 则对 gQUIC 做了“清理”,把应用部分分离出来,形成了 HTTP/3,原来的 UDP 部分“下放”到了传输层,所以 iQUIC 有时候也叫“QUIC-transport”。接下来要说的 QUIC 都是指 iQUIC,要记住,它与早期的 gQUIC 不同,是一个传输层的协议,和 TCP 是平级的.
聊到这里,我又想起了之前说过的话,如果一层不行,那就再加一层~ 。
了解了QUIC的基本概念,我们再来看看QUIC的特点,这样的特点给我们带来了哪些好处.
前面说过,QUIC是基于UDP的,而UDP是无连接的,根本就不需要握手和挥手,所以天生比TCP快很多.
就像 TCP 在 IP 的基础上实现了可靠传输一样,QUIC 也基于 UDP 实现了可靠传输,保证数据一定能够抵达目的地。它还引入了类似 HTTP/2 的“流”和“多路复用”,单个“流”是有序的,可能会因为丢包而阻塞,但其他“流”不会受到影响.
并且,QUIC全面使用加密通信,这样可以很好的抵御篡改和协议僵化.
另外,QUIC并不是建立在TLS之上的,而是内部包含了TLS。它使用自己的帧“接管”了 TLS 里的“记录”,握手消息、警报消息都不使用 TLS 记录,直接封装成 QUIC 的帧发送,省掉了一次开销.
QUIC的内容很多,我们只简单的聊一聊两个内部的关键知识点.
QUIC基本数据传输单位是包(packet)和帧(frame),一个包由多个帧组成,包面向的是”连接“,帧面向的是”流“.
QUIC 使用不透明的“ 连接 ID ”来标记通信的两个端点,客户端和服务器可以自行选择一组 ID 来标记自己,这样就解除了 TCP 里连接对“IP 地址 + 端口”(即常说的四元组)的强绑定,支持“连接迁移”(Connection Migration)。换句话说,当IP变化的时候,QUIC连接里的两端ID不会变,逻辑上连接没有中断,所以无需像TCP一样再重新连接,节省了一定的性能,消除了连接成本,实现连接的无缝迁移.
了解了QUIC后,再来学习HTTP/3就要容易很多了.
因为 QUIC 本身就已经支持了加密、流和多路复用,所以 HTTP/3 的工作减轻了很多,把流控制都交给 QUIC 去做。调用的不再是 TLS 的安全接口,也不是 Socket API,而是专门的 QUIC 函数。不过这个“QUIC 函数”还没有形成标准,必须要绑定到某一个具体的实现库.
HTTP/3 里仍然使用流来发送“请求 - 响应”,但它自身不需要像 HTTP/2 那样再去定义流,而是直接使用 QUIC 的流,相当于做了一个“概念映射”.
HTTP/3中的头部压缩算法也升级成了“QPACK”,使用方式上也做了改变。虽然也分成静态表和动态表,但在流上发送 HEADERS 帧时不能更新字段,只能引用,索引表的更新需要在专门的单向流上发送指令来管理,解决了 HPACK 的“队头阻塞”问题。另外,QPACK 的字典也做了优化,静态表由之前的 61 个增加到了 98 个,而且序号从 0 开始,也就是说“:authority”的编号是 0.
还有一个有趣的点是,HTTP/3 没有指定默认的端口号,也就是说不一定非要在 UDP 的 80 或者 443 上提供 HTTP/3 服务。那么,该怎么“发现”HTTP/3 呢?
这就要用到 HTTP/2 里的“扩展帧”了。浏览器需要先用 HTTP/2 协议连接服务器,然后服务器可以在启动 HTTP/2 连接后发送一个“Alt-Svc”帧,包含一个“h3=host:port”的字符串,告诉浏览器在另一个端点上提供等价的 HTTP/3 服务。浏览器收到“Alt-Svc”帧,会使用 QUIC 异步连接指定的端口,如果连接成功,就会断开 HTTP/2 连接,改用新的 HTTP/3 收发数据.
如果你想尝试HTTP/3的例子,我们可以在这个网址玩一下,https://quic.nginx.org/。如果不行的话,就需要多刷新几下,如果还是不行,那就需要打开Chrome浏览器在地址栏输入“chrome://flags”,打开设置页面,然后搜索“QUIC”,找到启用 QUIC 的选项,把它改为“Enabled”。就像这样:
然后,再去刷新几下,运气好的话,就可以看到这样的Network了:
如果你发现不管你怎么刷新都不行的话,试试把你的VPN关了应该会好的~ 。
这是整个H3的报文:
是不是有那么一点点陌生又熟悉?
本篇,我们简单的聊了聊HTTP/3,聊了聊QUIC是什么,它是怎么解决之前HTTP为之苦恼的队头阻塞的问题。以及HTTP/3的协议栈相比于HTTP/2、HTTP/1有什么区别,多了哪些内容等等。HTTP/3可以说是集大成之作,把之前所有版本的HTTP协议的精华摘取,去其糟粕,形成了现在几乎完美的HTTP/3协议.
那么关于“性能”部分,我们就到此为止了,后面我们会花几篇文章的时间,来学一学HTTPS,也就是HTTP是如何在“安全”这条路上走向完善的.
最后此篇关于真正“搞”懂HTTP协议14之HTTP3的文章就讲到这里了,如果你想了解更多关于真正“搞”懂HTTP协议14之HTTP3的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
internal protocol Reducer { associatedtype S : BaseState associatedtype A : BaseActi
我在考虑我的应用程序中的验证检查,我认为在任何模型上调用 ValidatorFactory,实现 Validee,这意味着说哪个类负责 ValidatorCreation 听起来不错。但是下面的代码不
我已经定义了 2 个协议(protocol)。我需要第一个 (NameProtocol) 来执行 Equatable 协议(protocol)。而另一个类 (BuilderProtocol) 有一个返
在上传方面,WebDAV 协议(protocol)在哪些方面优于 HTTP 协议(protocol)。 Socket Upload 协议(protocol)和 WebDav Upload 协议(pro
是否可以在任何版本的 Swift 中扩展具有混合类/协议(protocol)类型约束的协议(protocol)?例如,仅当 Self 是 UIViewController 的子类并且符合 Protoc
我有一个协议(protocol) (ProtocolA),其中包含符合第二个协议(protocol) (ProtocolB) 的单个属性。 public protocol ProtocolA {
NSObject 协议(protocol)带有常用的协议(protocol)模板,但它似乎并不是协议(protocol)实际实现所必需的。将其排除在外似乎完全没有任何改变。那么,协议(protocol
我想根据这两种协议(protocol)的一般特征(例如开销(数据包)、安全性、信息建模和可靠性)来比较 OPC UA 和 MQTT。我在哪里可以找到每个协议(protocol)的开销和其他特性的一些示
使用 Swift 4,我正在尝试编写一个自定义协议(protocol),它提供对 @objc 协议(protocol)的一致性。 一些代码 更具体地说,我有一个自定义协议(protocol) Sear
我想定义一个在 Viper 架构中使用的协议(protocol),以使用具有弱属性的协议(protocol)在 Viper 组件之间建立连接,但我收到以下错误消息: 'weak' may only b
我在同一个网络中有 3 个 docker 容器: 存储 (golang) - 它提供了用于上传视频文件的 API。 主播 (nginx) - 它流式传输上传的文件 反向代理 (姑且称之为代理) 我有
我打算在我的项目中使用 php socket。它需要用户登录才能根据 session 填充内容。所以我的问题是,TCP/IP 协议(protocol)也像 HTTP 协议(protocol)一样为每个
目前,我的网站有两个版本。一种带有 https://-证书,一种没有。我想将我网站的 http 版本上的所有用户 301 重定向到我网站的 https://版本。 这似乎不可能,因为创建重定向将导致重
目前,我的网站有两个版本。一种带有 https://-证书,一种没有。我想将我网站的 http 版本上的所有用户 301 重定向到我网站的 https://版本。 这似乎不可能,因为创建重定向将导致重
我有一个 Swift View Controller ,它定义了一个在 Objective-C View Controller 中应该遵循的协议(protocol): ChildViewControl
我在客户那里有数百个硬件设备,需要通过telnet接口(interface)发送HTTP数据。 目标是等待数据的 Apache 2 Web 服务器和 PHP 脚本。 这已经可以正常工作了,但是我们发现
我发现如果我创建一个这样的协议(protocol): protocol MyProtocol { } 我不能这样做: weak var myVar: MyProtocol? 我找到了解决这个问题的方法
Xcode 基于模板生成了这个头文件: // this file is XYZAppDelegate.h #import @interface XYZAppDelegate : UIRespond
我在 github 中有一个公开的存储库,我正在开发一个开源应用程序,用于制作产品目录和小型 cms 内容。 我还有一个私有(private)仓库(不托管在github),它是在托管在github的开
您好,我想让别人看到私有(private) repo 代码,但不想公开我的 repo ,也不希望他们有能力更改内容。这可能吗?我查看了网站的“管理”部分,但没有找到合适的内容。谢谢大家。 最佳答案 据
我是一名优秀的程序员,十分优秀!