You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

150 lines
11 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 33 | 我应该迁移到HTTP/2吗
这一讲是“飞翔篇”的最后一讲而HTTP的所有知识也差不多快学完了。
前面你已经看到了新的HTTP/2和HTTP/3协议了解了它们的特点和工作原理如果再联系上前几天“安全篇”的HTTPS你可能又会发出疑问
“刚费了好大的力气升级到HTTPS这又出了一个HTTP/2还有再次升级的必要吗
与各大浏览器“强推”HTTPS的待遇不一样HTTP/2的公布可谓是“波澜不惊”。虽然它是HTTP协议的一个重大升级但Apple、Google等科技巨头并没有像HTTPS那样给予大量资源的支持。
直到今天HTTP/2在互联网上还是处于“不温不火”的状态虽然已经有了不少的网站改造升级到了HTTP/2但普及的速度远不及HTTPS。
所以你有这样的疑问也是很自然的升级到HTTP/2究竟能给我们带来多少好处呢到底“值不值”呢
## HTTP/2的优点
前面的几讲主要关注了HTTP/2的内部实现今天我们就来看看它有哪些优点和缺点。
首先要说的是HTTP/2最大的一个优点是**完全保持了与HTTP/1的兼容**在语义上没有任何变化之前在HTTP上的所有投入都不会浪费。
因为兼容HTTP/1所以HTTP/2也具有HTTP/1的所有优点并且“基本”解决了HTTP/1的所有缺点安全与性能兼顾可以认为是“更安全的HTTP、更快的HTTPS”。
在安全上HTTP/2对HTTPS在各方面都做了强化。下层的TLS至少是1.2而且只能使用前向安全的密码套件即ECDHE这同时也就默认实现了“TLS False Start”支持1-RTT握手所以不需要再加额外的配置就可以自动实现HTTPS加速。
安全有了保障再来看HTTP/2在性能方面的改进。
你应该知道,影响网络速度的两个关键因素是“**带宽**”和“**延迟**”HTTP/2的头部压缩、多路复用、流优先级、服务器推送等手段其实都是针对这两个要点。
所谓的“带宽”就是网络的传输速度。从最早的56K/s到如今的100M/s虽然网速已经是“今非昔比”比从前快了几十倍、几百倍但仍然是“稀缺资源”图片、视频这样的多媒体数据很容易会把带宽用尽。
节约带宽的基本手段就是压缩在HTTP/1里只能压缩body而HTTP/2则可以用HPACK算法压缩header这对高流量的网站非常有价值有数据表明能节省大概5%~10%的流量,这是实实在在的“真金白银”。
与HTTP/1“并发多个连接”不同HTTP/2的“多路复用”特性要求对**一个域名或者IP只用一个TCP连接**所有的数据都在这一个连接上传输这样不仅节约了客户端、服务器和网络的资源还可以把带宽跑满让TCP充分“吃饱”。
这是为什么呢?
我们来看一下在HTTP/1里的长连接虽然是双向通信但任意一个时间点实际上还是单向的上行请求时下行空闲下行响应时上行空闲再加上“队头阻塞”实际的带宽打了个“对折”还不止可参考[第17讲](https://time.geekbang.org/column/article/104949))。
而在HTTP/2里“多路复用”则让TCP开足了马力“全速狂奔”多个请求响应并发每时每刻上下行方向上都有流在传输数据没有空闲的时候带宽的利用率能够接近100%。所以HTTP/2只使用一个连接就能抵得过HTTP/1里的五六个连接。
不过流也可能会有依赖关系可能会存在等待导致的阻塞这就是“延迟”所以HTTP/2的其他特性就派上了用场。
“优先级”可以让客户端告诉服务器哪个文件更重要更需要优先传输服务器就可以调高流的优先级合理地分配有限的带宽资源让高优先级的HTML、图片更快地到达客户端尽早加载显示。
“服务器推送”也是降低延迟的有效手段它不需要客户端预先请求服务器直接就发给客户端这就省去了客户端解析HTML再请求的时间。
## HTTP/2的缺点
说了一大堆HTTP/2的优点再来看看它有什么缺点吧。
听过上一讲HTTP/3的介绍你就知道HTTP/2在TCP级别还是存在“队头阻塞”的问题。所以如果网络连接质量差发生丢包那么TCP会等待重传传输速度就会降低。
另外在移动网络中发生IP地址切换的时候下层的TCP必须重新建连要再次“握手”经历“慢启动”而且之前连接里积累的HPACK字典也都消失了必须重头开始计算导致带宽浪费和时延。
刚才也说了HTTP/2对一个域名只开一个连接所以一旦这个连接出问题那么整个网站的体验也就变差了。
而这些情况下HTTP/1反而不会受到影响因为它“本来就慢”而且还会对一个域名开6~8个连接顶多其中的一两个连接会“更慢”其他的连接不会受到影响。
## 应该迁移到HTTP/2吗
说到这里你对迁移到HTTP/2是否已经有了自己的判断呢
在我看来HTTP/2处于一个略“尴尬”的位置前面有“老前辈”HTTP/1后面有“新来者”HTTP/3即有“老前辈”的“打压”又有“新来者”的“追赶”也就难怪没有获得市场的大力“吹捧”了。
但这绝不是说HTTP/2“一无是处”实际上HTTP/2的性能改进效果是非常明显的Top 1000的网站中已经有超过40%运行在了HTTP/2上包括知名的Apple、Facebook、Google、Twitter等等。仅用了四年的时间HTTP/2就拥有了这么大的市场份额和巨头的认可足以证明它的价值。
因为HTTP/2的侧重点是“性能”所以“是否迁移”就需要在这方面进行评估。如果网站的流量很大那么HTTP/2就可以带来可观的收益反之如果网站流量比较小那么升级到HTTP/2就没有太多必要了只要利用现有的HTTP再优化就足矣。
不过如果你是新建网站我觉得完全可以跳过HTTP/1、HTTPS直接“一步到位”上HTTP/2这样不仅可以获得性能提升还免去了老旧的“历史包袱”日后也不会再有迁移的烦恼。
顺便再多嘴一句HTTP/2毕竟是“下一代”HTTP协议它的很多特性也延续到了HTTP/3提早升级到HTTP/2还可以让你在HTTP/3到来时有更多的技术积累和储备不至于落后于时代。
## 配置HTTP/2
假设你已经决定要使用HTTP/2应该如何搭建服务呢
因为HTTP/2“事实上”是加密的所以如果你已经在“安全篇”里成功迁移到了HTTPS那么在Nginx里启用HTTP/2简直可以说是“不费吹灰之力”只需要在server配置里再多加一个参数就可以搞定了。
```
server {
listen 443 ssl http2;
server_name www.xxx.net;
ssl_certificate xxx.crt;
ssl_certificate_key xxx.key;
```
注意“listen”指令在“ssl”后面多了一个“http2”这就表示在443端口上开启了SSL加密然后再启用HTTP/2。
配置服务器推送特性可以使用指令“http2\_push”和“http2\_push\_preload”
```
http2_push /style/xxx.css;
http2_push_preload on;
```
不过如何合理地配置推送是个难题,如果推送给浏览器不需要的资源,反而浪费了带宽。
这方面暂时没有一般性的原则指导,你必须根据自己网站的实际情况去“猜测”客户端最需要的数据。
优化方面HTTPS的一些策略依然适用比如精简密码套件、ECC证书、会话复用、HSTS减少重定向跳转等等。
但还有一些优化手段在HTTP/2里是不适用的而且还会有反效果比如说常见的精灵图Spriting、资源内联inlining、域名分片Sharding至于原因是什么我把它留给你自己去思考提示与缓存有关
还要注意一点HTTP/2默认启用header压缩HPACK但并没有默认启用body压缩所以不要忘了在Nginx配置文件里加上“gzip”指令压缩HTML、JS等文本数据。
## 应用层协议协商ALPN
最后说一下HTTP/2的“服务发现”吧。
你有没有想过在URI里用的都是HTTPS协议名没有版本标记浏览器怎么知道服务器支持HTTP/2呢为什么上来就能用HTTP/2而不是用HTTP/1通信呢
答案在TLS的扩展里有一个叫“**ALPN**”Application Layer Protocol Negotiation的东西用来与服务器就TLS上跑的应用协议进行“协商”。
客户端在发起“Client Hello”握手的时候后面会带上一个“ALPN”扩展里面按照优先顺序列出客户端支持的应用协议。
就像下图这样最优先的是“h2”其次是“http/1.1”以前还有“spdy”以后还可能会有“h3”。
![](https://static001.geekbang.org/resource/image/d8/b0/d8f8606948bbd63c31466e464c1956b0.png)
服务器看到ALPN扩展以后就可以从列表里选择一种应用协议在“Server Hello”里也带上“ALPN”扩展告诉客户端服务器决定使用的是哪一种。因为我们在Nginx配置里使用了HTTP/2协议所以在这里它选择的就是“h2”。
![](https://static001.geekbang.org/resource/image/19/a7/19be1138574589458c96040e1a23b3a7.png)
这样在TLS握手结束后客户端和服务器就通过“ALPN”完成了应用层的协议协商后面就可以使用HTTP/2通信了。
## 小结
今天我们讨论了是否应该迁移到HTTP/2还有应该如何迁移到HTTP/2。
1. HTTP/2完全兼容HTTP/1是“更安全的HTTP、更快的HTTPS”头部压缩、多路复用等技术可以充分利用带宽降低延迟从而大幅度提高上网体验
2. TCP协议存在“队头阻塞”所以HTTP/2在弱网或者移动网络下的性能表现会不如HTTP/1
3. 迁移到HTTP/2肯定会有性能提升但高流量网站效果会更显著
4. 如果已经升级到了HTTPS那么再升级到HTTP/2会很简单
5. TLS协议提供“ALPN”扩展让客户端和服务器协商使用的应用层协议“发现”HTTP/2服务。
## 课下作业
1. 和“安全篇”的第29讲类似结合自己的实际情况分析一下是否应该迁移到HTTP/2有没有难点
2. 精灵图Spriting、资源内联inlining、域名分片Sharding这些手段为什么会对HTTP/2的性能优化造成反效果呢
欢迎你把自己的学习体会写在留言区,与我和其他同学一起讨论。如果你觉得有所收获,也欢迎把文章分享给你的朋友。
![unpreview](https://static001.geekbang.org/resource/image/fb/55/fb986a7575ec902c86c17a937dbca655.png)