Notes
Search…
Notes
Introduce
Go
Grammar
System Library
Concurrency in Go
The Go Memory Model
Rust
The Rust Programming Language
Rust by Example
JAVA
Preface
Grammar
Class Libraries
Concurrency
JVM
Web Container
Spring
Tuning
Computer Science
Computer Organization
Algorithm
Network Protocol
Pysical Layer
Data Link Layer
Network Layer
Transport Layer
Application layer
HTTP
HTTP/2 in Action
Operating System
Design Patterns
Microservice
Distributed System
database
InfluxDB
MySQL
Redis
Elasticsearch
HBase
Kafka
ZooKeeper
MongoDB
Reading
RocketMQ
演说之禅
Other
v2ray
Kubernetes
Git
Maven
Anaconda And Conda
Fuck! Shit!
Open source contribution
Powered By
GitBook
HTTP/2 in Action
《HTTP/2 in Action》by Barry Pollard 的读书笔记。
Part 1. 向 HTTP/2 靠拢
Chapter 1. 万维网与 HTTP
1.1 万维网的原理
因特网使用 IP(Internet Protocol)协议,万维网(World Wide Web)有三项核心技术,HTTP、URL、HTML。
1.2 什么是 HTTP
HTTP 代表超文本传输协议。基于可靠的网络连接,通常为 TCP/IP。是一个请求-响应协议。
1.3 HTTP 的语法和历史
HTTP/0.9: 没有 header、body,每个请求关闭连接,错误用 HTML 响应文本。
HTTP/1.0: 更多请求方法,添加版本号字段,首部,整数响应状态码
HTTP/1.1: 对 1.0 的标准化和完善。强制添加 Host header,持久连接(默认),管道(不流行,且支持较差),cookie。
1.4 HTTPS
HTTP 的安全版本,加密、完整性校验、身份验证。使用 TLS(Transport Layer Security)加密,TLS 的前身是 SSL(Secure Sockets layer)。
HTTPS的一个重大问题是,它只保证你正在连接到该服务器,而不能保证服务器值得信任。
1.5 查看、发送和接收 HTTP 消息的工具
浏览器开发者。
Postman,curl,wget。
Chapter 2. 通向 HTTP/2 之路
2.1 HTTP 和当前的万维网
在一个连接中,请求 1-> 响应 1 -> 请求 2 -> 响应 2 的工作方式是 HTTP 慢的根本原因,即为了等待响应会阻塞发送,在当前请求完成之前,无法发送另一个请求。
HTTP/1.1 引入管道化,连续发出多个请求,并按照顺序接收响应。但是很难实现,没有一个主流的 Web 浏览器支持管道化技术。而且存在队头(HOL)阻塞问题。
2.2 解决 HTTP/1.1 性能问题的方案
大致分为两类:
使用多个 HTTP连接
合并 HTTP 请求
使用多连接与管道化相比,不会有 HOL 阻塞问题。多数浏览器可以为每个域名分配 6 个连接。域名分片技术可以开启更多连接。但是也有缺点,建立连接需要时间,维护连接需要 CPU 和内存,TCP 的慢启动算法导致每个连接初始的拥塞窗口都很小。
发送更少的请求,精灵图,CSS 和 JavaScript 文件合并,最小化文件。缺点是引入了复杂度;合并文件会导致浪费,因为不是所有的网站都需要合并文件的所有内容;缓存。
2.3 HTTP/1.1 的其他问题
请求和首部是文本形式,对人类友好,但对机器不友好。
首部内容重复,尤其是 cookie。
2.5 从 HTTP/1.1 到 HTTP/2
SPDY:流多路利用,请求优先级,HTTP 首部压缩,服务器推送。二进制协议。
HTTP/2 是基于 SPDY 的标准化版本。
2.6 HTTP/2 对 Web 性能的影响
大多数网站可以带来很大性能提升。但不能解决所有的性能问题。
Chapter 3. 升级到 HTTP/2
3.1 HTTP/2 的支持
几乎每个现代浏览器都支持 HTTP/2,仅支持基于 HTTPS 的 HTTP/2 是浏览器厂商遵循的事实上的标准。但是中间代理若不支持,可能降级为 1.1。
几乎所有的服务器也都支持 HTTP/2 了,但是服务器升级比较麻烦,且升级 SSL/TLS 库更麻烦。
如果中间有一环不能支持 HTTP/2,可以降级到 1.1。
3.2 网站开启 HTTP/2 的方法
Web 服务器开启 HTTP/2。
在 Web 服务器前放置一个 HTTP/2 的反向代理服务器,将 HTTP/2 转换为 HTTP/1.1 发送给 Web 服务器。
通过 CDN 实现 HTTP/2。
3.3 常见问题
Web 服务器未启用 ALPN 支持,有些浏览器仅支持 ALPN。ALPN 是 TLS 的扩展。
Part 2. 使用 HTTP/2
Chapter 4. HTTP/2 协议基础
4.1 为什么是 HTTP/2 而不是 HTTP/1.2
因为增加了很多概念,是根本上的变化,不向前兼容。
二进制的、基于数据包的协议,而 HTTP/1 是完全基于文本的。
多路复用替代同步请求,每个帧分配一个流标识符表名属于哪个流。客户端发起的请求使用奇数流 ID,服务器使用偶数流 ID。ID 为 0 的流为管理连接的控制流。
流有优先级。
流可以流量控制。TCP 在连接层限流,HTTP/2 在流的层面限流。
首部压缩,cookie、user-agent、host、accept-encoding 等基本不变。HTTP/1 仅允许压缩 body。HTTP/2 还能跨请求压缩首部。
服务端推送。
4.2 如何创建一个 HTTP/2 连接
浏览器仅支持基于 HTTPS(h2) 建立 HTTP/2,服务器之间可以基于 HTTP(h2c) 的 HTTP/2。
使用 HTTPS 协商,在 HTTPS 握手过程中,同时完成 HTTP/2 协商。ALPN 不会引入额外的消息往返。
使用 HTTP Upgrade header,仅适用于 h2c。客户端发起升级请求,服务端响应是否支持,客户端决定是否升级。
使用先验知识。
不管使用哪种方法启用HTTP/2连接,在HTTP/2连接上发送的第一个消息必须是HTTP/2连接前奏,或者说是“魔法”字符串。
4.3 HTTP/2 帧
每个HTTP/2帧由一个固定长度的头部和不定长度的负载组成。
HTTP/2 帧头部格式
标志位的含义和值取决于帧类型。
SETTING 帧:服务器和客户端必须发送的第一个帧(除了魔法字符串),只包含键值对。流 ID 为 0。标志位 0 表示发起设置,标志位 1 表示确认设置。
WINDOW_UPDATE 帧:用于流量控制。流量控制仅用于 DATA 帧。
PRIORITY 帧:优先级设定。
HEADERS 帧:冒号开头是严格定义的伪首部,不能自己随便添加。可以自定义非冒号开头的普通 header。有四个标志位:END_
STREAM, END_
HEADERS, PADDED, PRIORITY
DATA 帧:消息体。
GOAWAY 帧:错误或关闭连接。
CONTINUATION 帧:太大的首部需要。必须紧跟在 HEADERS 帧后面。降低了多路复用性。
PING 帧:计算消息往返时间。保持一个不使用的连接。
PUSH_PROMISE 帧:服务端通知客户端要发起推送。
RST_STREAM 帧:直接取消一个流。
ALTSVC 帧:允许服务端宣告获取资源时可用的其他服务。
ORIGIN 帧:服务器使用它来宣告自己可以处理哪些源(比如域名)的请求。
CACHE_DIGEST 帧:客户端可以使用这个帧来表明自己缓存了哪些资源。
Chapter 5. 实现 HTTP/2 推送
5.1 什么是 HTTP/2 服务端推送
HTTP/2服务端推送(以下称为HTTP/2推送)允许服务器发回客户端未请求的额外资源。
若服务端知道此页面需要哪些关键资源,不需要等客户端请求而是直接推送,则能减少往返次数。
需要注意的一个关键点是,仅在响应初始请求时才会发送推送的资源。HTTP/2中不是真正的双向流。推送资源是为了响应初始请求而做出的额外响应。完成该初始请求后,流会被关闭,除非客户端发起其他请求,否则不能推送其他资源。
5.2 如何推送
使用HTTP link首部通知Web服务器推送资源。
可以从下游系统推送:
可以更早推送:
不需要在整个链路中都支持推送。
5.3 HTTP/2 推送在浏览器中如何运作
资源不是被直接推到网页中,而是被推到缓存中。
HTTP/2推送缓存被绑定到连接,而不是页面。当资源从连接的推送缓存中被“认领”并拿出后,就不能再从推送缓存中使用它了。推送缓存还有一点和HTTP缓存不同,那就是不缓存的资源(在HTTP cache-control首部中设置了no-cache和no-store)也可以被推送,并可以从推送缓存中读取它们。
客户端可以通过发送RST_STREAM帧来拒绝推送资源。
5.4 如何实现条件推送
服务器可以记录它在一个客户端的连接上推送过哪些资源。
客户端发送一个if-modified-since或者etag首部。
在客户端记录哪些资源已经被推送。cookie是做这个的理想载体。
缓存摘要是一个提议,浏览器用它来告诉服务器缓存里有什么内容。
5.5 推送什么
推送需要的最少资源,来“填充空闲的网络时间,不要做多余的操作。
5.6 HTTP/2 推送的常见问题
很多原因可能导致没有 HTTP/2 推送。
5.7 HTTP/2 推送对性能的影响
高效使用HTTP/2推送的关键是利用连接未被使用时的空闲带宽。
5.8 对比推送和预加载
预加载没有HTTP/2推送那么快,但是它是一个浏览器发起的请求,有一些优势:
浏览器知道缓存里有什么,然后它就知道是否要发出对应的请求。
没有那么多复杂性。
可以从其它域名加载资源。
5.9 HTTP/2 推送的其它应用场景
Chapter 6. HTTP/2 优化
6.1 HTTP/2 对 Web 开发者的影响
HTTP/2在设计上是向后兼容的。
6.2 一些 HTTP/1.1 中的优化方法是否成了反模式
压缩大文件比压缩小文件效果好。总的来说,HTTP/2可能不需要像HTTP/1.1那样有那么多的资源合并,但是在拆分文件之前要考虑一下带来的压缩率下降问题。
在HTTP/2的世界里,域名分片的意义没有那么大,并且设置和管理这些额外的基础设施也是一种负担。
HTTP/2推送要消除对内联资源的需求。
6.3 在 HTTP/2 下依然有效的性能优化技术
不管HTTP/2提供了哪些方法来优化请求和响应,少发送数据总是好的。比如使用合适的文件格式和大小,压缩文本数据。
使用缓存防止重复发送数据。
Service Worker可以大幅减少网络加载。
6.4 同时对 HTTP/1.1 和 HTTP/2 做优化
连接合并。HTTP/2规范允许多个域名使用同一个HTTP/2连接,这些域名被解析到同一个IP地址。
Part 3. HTTP/2 进阶
Chapter 7. 高级 HTTP/2 概念
7.1 流状态
流不会被重用。流是一个虚拟的概念,它是在每个帧上标示的一个数字,也就是流ID。
7.2 流量控制
在HTTP/1.1下流量控制不是必需的,因为不管何时最多只会有一个消息在传输。因此,可以使用连接层的TCP流量控制。
在HTTP/2下,使用由多个流组成的多路复用的连接,所以只使用连接层的流量控制就不够了。不仅需要连接层的控制,还需要流层级的控制。
7.3 流优先级
优先级是一种建议或提示,完全由响应方决定要不要忽略优先级。
有两种方式设置优先级:
流依赖
流权重
使用流优先级的目的是尽量高效利用连接,而不是作为一种阻塞机制。
新增的流还可以是排他的。
为了使优先级模型更简单,一些客户端会使用PRIORITY帧预设置一些假流,并为它们设置对应的优先级,然后将请求挂在这些流下面。在HTTP/2标准制定的后期才添加了支持假PRIORITY帧的概念,它是更灵活的方案,支持更轻量的优先级模型。这些假流仅用于优先级排序,永远不会被用来直接发送请求。
规定一定要支持流优先级策略,很多客户端和服务端的实现都选择不实现优先级策略。
7.4 HTTP/2 一致性测试
H2spec是一个HTTP/2一致性测试工具,它发送不同的消息到HTTP/2服务器,并检查服务器是否正确遵守规范。
很多HTTP/2的实现不严格遵守规范。
Chapter 8. HPACK 首部压缩
8.1 为什么需要首部压缩
首部重复很多。有些首部很长,如 cookie。
8.2 压缩的运作方式
有损压缩常用于媒体。
无损压缩常见三种方法:
查表法。
更高效的编码技术:Huffman编码是更进一步的可变长度编码。它的工作原理是根据每个值的使用频率为其分配一个唯一代码,并且保证没有一个代码是其他代码的前缀。
lookback(反查)压缩。
8.3 HTTP 正文压缩
浏览器通过accept-encodingHTTP首部告诉服务器它所支持的压缩算法。HTTP正文压缩通常用于文本数据,gzip。
8.4 HTTP/2 的 HPACK 首部压缩
HPACK(不是简写),它基于查询表和Huffman编码,但(关键)不是基于反查的压缩方法。
HPACK格式被有意保持简单且死板。这两个特征都会减少因为实现错误所带来的互操作风险,或者安全问题。没有定义扩展机制,如要改变当前格式,只能使用一个完整的替代品。
HPACK有一个静态表,包含61个常见的HTTP首部名称(有些还有值)。对于表中首部名/首部值组合(比如:method: GET)这种条目,可以只使用其中的首部名部分(如:method)。
除了静态表以外,HPACK还有一个连接级的动态表,从位置62开始(跟在静态表之后),在会话过程中创建。
没有引用索引表的首部值可以使用ASCII编码或者Huffman编码来传输。
Huffman编码通常占用更少的空间。
8.5 HPACK 压缩实例
8.6 客户端和服务端对 HPACK 的实现
在HPACK中可以使用多种方法来发送HTTP首部,浏览器可能使用不同的方式来编码HTTP首部。
8.7 HPACK 的价值
Part 4. HTTP 的未来
Chapter 9. TCP、QUIC 和 HTTP/3
9.1 TCP 的低效因素,以及 HTTP
TCP 连接和 HTTPS 的建立导致延时。
TCP 慢启动算法,初始的窗口很小。
实际上,TCP的拥塞避免阶段的增长更慢。6个连接的话,每个连接都要经历这个过程。
TCP比较小心谨慎,在闲置一段时间后,网络情况可能发生变化,所以TCP将拥塞窗口大小降低,重新进行慢启动流程。
TCP还把丢包当成极端事件。它认为这个事件是由容量限制造成的,因而它会做出激烈反应,直接将拥塞窗口大小减半。认为丢包完全是由拥堵造成的,然后大幅降低网速,这是不正确的。新的TCP拥塞控制算法对网络丢包的处理不像之前的示例中那么极端,它们可能将拥塞窗口调小一些(不到一半),在丢包之后让其快速增长(类似慢启动),或者使用其他指标来决定要不要调整容量(比如把平均的往返时间当作更好的指标)。
认为丢包完全是由拥堵造成的,然后大幅降低网速,这是不正确的。新的TCP拥塞控制算法对网络丢包的处理不像之前的示例中那么极端,它们可能将拥塞窗口调小一些(不到一半),在丢包之后让其快速增长(类似慢启动),或者使用其他指标来决定要不要调整容量(比如把平均的往返时间当作更好的指标)。
HTTP/2在HTTP层解决了队头阻塞(HOL)的问题,因为有多路复用,单个响应的延迟不会影响其他资源使用当前的HTTP连接。但是,在TCP层队头阻塞依然存在。一个流的丢包会直接影响到其他所有的流,尽管它们可能不需要排队。在严重的丢包情况下,HTTP/2的性能会更糟。
TCP有了很多优化和创新。然而不幸的是,TCP通常由底层操作系统控制,我们在操作系统之外很少有机会更改它。所以,最佳使用TCP的方法就是使用最新版本的操作系统。
CP可以使用SACK(Selective Acknowledgment,选择性响应)响应乱序的数据包,以避免丢包时重传。
可以配置禁止重启慢启动。
TFO(TCP Fast Open,TCP快速打开)允许使用TCP三次握手的初始SYN部分发送初始数据包。出于安全的原因,这个数据包只能在TCP重连时使用,而不能在初次连接时使用。
TFO带来的提升真的很显著。Google曾经表示:“通过对网络流量的分析和网络仿真,我们得出TFO能够将HTTP网络延迟降低15%,网页整页加载时间平均降低10%,有时候能降低40%。
使用拥塞控制算法,PRR和BBR。BBR(Bottleneck Bandwidth and Round-trip propagation time,瓶颈带宽和往返时间),已经有数据表明它可以大幅度提升性能[17],特别是对于HTTP/2连接。
9.2 QUIC
QUIC(发音同quick)是Google(又是Google)发明的一个基于UDP的协议。
FEC(Forward Error Correction,前向纠错)试图通过在邻近的数据包中添加一个QUIC数据包的部分数据来减少数据包重传的需求。这个想法是,如果只丢了一个数据包,那应该可以从成功传送的数据包中重新组合出该数据包。这个方法可以类比于“网络世界的RAID 5。
连接迁移旨在减少连接创建的开销,它通过支持连接在网络之间迁移来实现。
多路径的技术同时使用Wi-Fi和移动网络进行一次QUIC连接。
QUIC取代了TCP提供的大多数功能(创建连接、可靠性和拥塞控制部分),取代了HTTPS的全部(降低了创建延迟),甚至还有HTTP/2的一部分(流量控制和首部压缩)功能。
QUIC不会替代HTTP/2,但它会接管传输层的一些工作,在上层运行较轻的HTTP/2实现。
UDP是一种基础协议,也在内核中实现。在它之上的任何东西都需要在应用层中构建,也就是所说的用户空间。
UDP并非没有问题。它是一种常见的协议,但不像TCP使用那么普遍。UDP的另一个问题是,用户空间并不总是与高度优化的内核空间一样高效。
QUIC旨在成为一种通用的协议,HTTP只是它的一种用途。虽然HTTP目前是QUIC的主要用例,也是工作组目前正在关注的焦点,但该协议的设计考虑了潜在的其他应用场景。
HTTPS内置于QUIC中,与HTTP/2不同,QUIC不能用于未加密的HTTP连接。
Chapter 10. HTTP 将何去何从
10.1 关于 HTTP/2 的争议,以及它没有解决的问题
HTTP/2的隐私问题饱受争议。
10.2 HTTP/2 的实际应用
10.3 HTTP/2 的未来版本,HTTP/3 或者 HTTP/4 会带来什么
10.4 将 HTTP 当做一个更通用的传输协议
基于HTTPS的DNS(DoH)。
Previous
HTTP
Next - Computer Science
Operating System
Last modified
7mo ago
Copy link
Contents
Part 1. 向 HTTP/2 靠拢
Chapter 1. 万维网与 HTTP
Chapter 2. 通向 HTTP/2 之路
Chapter 3. 升级到 HTTP/2
Part 2. 使用 HTTP/2
Chapter 4. HTTP/2 协议基础
Chapter 5. 实现 HTTP/2 推送
Chapter 6. HTTP/2 优化
Part 3. HTTP/2 进阶
Chapter 7. 高级 HTTP/2 概念
Chapter 8. HPACK 首部压缩
Part 4. HTTP 的未来
Chapter 9. TCP、QUIC 和 HTTP/3
Chapter 10. HTTP 将何去何从