You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
consthttp2=require('http2');constfs=require('fs');constserver=http2.createSecureServer({key: fs.readFileSync('localhost-privkey.pem'),cert: fs.readFileSync('localhost-cert.pem')});server.on('error',(err)=>console.error(err));server.on('stream',(stream,headers)=>{// stream is a Duplexstream.respond({'content-type': 'text/html',':status': 200});stream.end('<h1>Hello World</h1>');});server.listen(8443);
概述
可以说,HTTP/2任重而道远,虽然现在还没有普及开来,但是HTTP/2是兼容HTTP1的语义的。
HTTP/2的目标
与 HTTP/1.1 相比,HTTP/2 的主要变化在于性能提升。
HTTP/1.x 客户端需要使用多个连接才能实现并发和缩短延迟;HTTP/1.x 不会压缩请求和响应标头,从而导致不必要的网络流量;HTTP/1.x 不支持有效的资源优先级,致使底层 TCP 连接的利用率低下;等等。
这些限制并不是致命的,但是随着网络应用的范围、复杂性以及在我们日常生活中的重要性不断增大,它们对网络开发者和用户都造成了巨大负担,而这正是 HTTP/2 要致力于解决的:
HTTP/2 通过支持标头字段压缩和在同一连接上进行多个并发交换,让应用更有效地利用网络资源,减少感知的延迟时间。具体来说,它可以对同一连接上的请求和响应消息进行交错发送并为 HTTP 标头字段使用有效编码。 HTTP/2 还允许为请求设置优先级,让更重要的请求更快速地完成,从而进一步提升性能。出台的协议对网络更加友好,因为与 HTTP/1.x 相比,可以使用更少的 TCP 连接。
通信过程
当客户端发起请求的时候,服务器会通过ALPN来协商最终使用HTTP2还是HTTP1来通信。这有利于当服务器或者客户端有一方不支持HTTP2时回退到HTTP1。
之后双方在建立的TCP上进行通信,是全双工传输方式,而且请求不会被阻塞排队。
特征细说
二进制分帧
HTTP/2 所有性能增强的核心在于新的二进制分帧层,它定义了如何封装 HTTP 消息并在客户端与服务器之间传输。
HTTP/1.x 协议以换行符作为纯文本的分隔符,而 HTTP/2 将所有传输的信息分割为更小的消息和帧,并采用二进制格式对它们编码。
HTTP/2帧结构
所有的帧都以一个固定的9字节首部开始,其后紧跟一个可变长度的载荷。
帧类型:
HTTP/2二进制分帧机制
三个相关的概念:
它们的关系:
请求与响应复用
在 HTTP/1.x 中,如果客户端要想发起多个并行请求以提升性能,则必须使用多个 TCP 连接。
HTTP/2 中新的二进制分帧层突破了这些限制,实现了完整的请求和响应复用:客户端和服务器可以将 HTTP 消息分解为互不依赖的帧,然后交错发送,最后再在另一端把它们重新组装起来。
拓展一下,联级文件(如Webpack打包模块),image sprites(雪碧图),域名分片等等都是为了绕过 HTTP/1.x 限制而做的工作。
所以HTTP/2 中的新二进制分帧层解决了 HTTP/1.x 中存在的队首阻塞问题,也消除了并行处理和发送请求及响应时对多个连接的依赖。结果,应用速度更快、开发更简单、部署成本更低。
数据流优先级
TTP/2 标准允许每个数据流都有一个关联的权重和依赖关系:
流控制
流控制是一种阻止发送方向接收方发送大量数据的机制,以免超出后者的需求或处理能力:发送方可能非常繁忙、处于较高的负载之下,也可能仅仅希望为特定数据流分配固定量的资源。
HTTP/2 提供了一组简单的构建块,这些构建块允许客户端和服务器实现其自己的数据流和连接级流控制:
扩展一下,如果这个功能足够强大的话是可以取代现在的懒加载模式的。
压缩头字段
每个 HTTP 传输都承载一组标头,这些标头说明了传输的资源及其属性。 在 HTTP/1.x 中,此元数据始终以纯文本形式,通常会给每个传输增加 500–800 字节的开销。如果使用 HTTP Cookie,增加的开销有时会达到上千字节。
为了减少此开销和提升性能,HTTP/2 使用 HPACK 压缩格式压缩请求和响应标头元数据,这种格式采用两种简单但是强大的技术:
zlib 压缩算法被 HPACK 替代,后者经过专门设计,可以解决发现的安全问题、实现起来也更高效和简单,当然,可以对 HTTP 标头元数据进行良好压缩。
HPACK 压缩上下文包含一个静态表和一个动态表:静态表在规范中定义,并提供了一个包含所有连接都可能使用的常用 HTTP 标头字段(例如,有效标头名称)的列表;动态表最初为空,将根据在特定连接内交换的值进行更新。因此,为之前未见过的值采用静态 Huffman 编码,并替换每一侧静态表或动态表中已存在值的索引,可以减小每个请求的大小。
服务器推送
HTTP/2 新增的另一个强大的新功能是,服务器可以对一个客户端请求发送多个响应。 换句话说,除了对最初请求的响应外,服务器还可以向客户端推送额外资源,而无需客户端明确地请求。
推送资源可以进行以下处理:
从开发者的视角
如果是Web前端开发者的话,其实还算友好,因为浏览器几乎都支持了HTTP/2,我们只需要像往常一样调用Web API,浏览器会通过ALPN和服务器协商使用HTTP/2还是HTTP/1。
Android和iOS可以通过相关的库支持HTTP/2。
对于后端开发者来说,工作量就相对有点大了。因为HTTP/2改变了传输方式,所以几乎所有编程语言会提供新的API,也就意味着需要重构项目。我们可以看看NodeJS是怎么构建一个HTTP/2服务器的:
1. 创建RSA
因为HTTP/2是依赖TLS/SSL,所以我们需要创建RSA,下面的指令是Unix环境下的,win10系统可以通过Microsoft Store下载Ubuntu 18来执行:
openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \ -keyout localhost-privkey.pem -out localhost-cert.pem
win10系统可以通过下面的路径找到生成的两个文件:
2. 构建HTTP/2服务器
创建HTTP/2服务器的时候需要传入第一步创建的RSA。
还有HTTP/2服务器不再是监听data事件,而是stream事件。
参考
HTTP/2 简介
HTTP/2 幕后原理
HTTP Alternative Services 介绍
HTTP2学习笔记
《HTTP/2基础教程》
The text was updated successfully, but these errors were encountered: