HTTP 2.0 初体验

2,472 阅读14分钟

背景

从 HTTP 2.0 发布至今,已经越来越多的网站开始部署 HTTP/2 了,正好最近一直在研究前端性能优化,就决定在个人网站先尝尝鲜。

HTTP/2 概述

官网先来一波HTTP/2 官网,HTTP 2.0 的出现,相比于 HTTP 1.x ,做出了很多优化调整,大幅提升了前端 web 性能,减少网络延迟等等。 HTTP/2: the Future of the Internet | Akamai这是 Akamai 公司建立的一个官方的演示,用以说明 HTTP/2 相比于之前的 HTTP/1.1 在性能上的大幅度提升。 同时请求 379 张图片,从 Load time 的对比可以看出 HTTP/2 在速度上的优势。 关于 HTTP/2 百度内容很多,下面我列出比较好的 HTTP/2 内容的地址,大家可以去这些地址查看。

  1. HTTP/2.0 相比 1.0 有哪些重大改进? 来自知乎
  2. HTTP/2 资料汇总 推荐,从协议本身,到部署优化,再到工具调试和参开书籍等都包含了。
  3. HTTP,HTTP2.0,SPDY,HTTPS 看这篇就够了
  4. HTTP、HTTP2.0、SPDY、HTTPS 你应该知道的一些事

下面内容 来自上面链接第四个,可以直接去查看原文,也可以在本文查看。

web 始祖 HTTP

全称:超文本传输协议(HyperText Transfer Protocol) 伴随着计算机网络和浏览器的诞生,HTTP1.0 也随之而来,处于计算机网络中的应用层,HTTP 是建立在 TCP 协议之上,所以 HTTP 协议的瓶颈及其优化技巧都是基于 TCP 协议本身的特性,例如 tcp 建立连接的 3 次握手和断开连接的 4 次挥手以及每次建立连接带来的 RTT 延迟时间。

HTTP 与现代化浏览器

早在 HTTP 建立之初,主要就是为了将超文本标记语言(HTML)文档从 Web 服务器传送到客户端的浏览器。也是说对于前端来说,我们所写的 HTML 页面将要放在我们的 web 服务器上,用户端通过浏览器访问 url 地址来获取网页的显示内容,但是到了 WEB2.0 以来,我们的页面变得复杂,不仅仅单纯的是一些简单的文字和图片,同时我们的 HTML 页面有了 CSS,Javascript,来丰富我们的页面展示,当 ajax 的出现,我们又多了一种向服务器端获取数据的方法,这些其实都是基于 HTTP 协议的。同样到了移动互联网时代,我们页面可以跑在手机端浏览器里面,但是和 PC 相比,手机端的网络情况更加复杂,这使得我们开始了不得不对 HTTP 进行深入理解并不断优化过程中。

HTTP 的基本优化

影响一个 HTTP 网络请求的因素主要有两个:带宽和延迟。

  • 带宽:如果说我们还停留在拨号上网的阶段,带宽可能会成为一个比较严重影响请求的问题,但是现在网络基础建设已经使得带宽得到极大的提升,我们不再会担心由带宽而影响网速,那么就只剩下延迟了。
  • 延迟
    1. **浏览器阻塞(HOL blocking):**浏览器会因为一些原因阻塞请求。浏览器对于同一个域名,同时只能有 4 个连接(这个根据浏览器内核不同可能会有所差异),超过浏览器最大连接数限制,后续请求就会被阻塞。
    2. **DNS 查询(DNS Lookup):**浏览器需要知道目标服务器的 IP 才能建立连接。将域名解析为 IP 的这个系统就是 DNS。这个通常可以利用 DNS 缓存结果来达到减少这个时间的目的。
    3. **建立连接(Initial connection):**HTTP 是基于 TCP 协议的,浏览器最快也要在第三次握手时才能捎带 HTTP 请求报文,达到真正的建立连接,但是这些连接无法复用会导致每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显,慢启动则对文件类大请求影响较大。

HTTP1.0 和 HTTP1.1 的一些区别

HTTP1.0 最早在网页中使用是在 1996 年,那个时候只是使用一些较为简单的网页上和网络请求上,而 HTTP1.1 则在 1999 年才开始广泛应用于现在的各大浏览器网络请求中,同时 HTTP1.1 也是当前使用最为广泛的 HTTP 协议。 主要区别主要体现在:

  1. **缓存处理:**在 HTTP1.0 中主要使用 header 里的 If-Modified-Since,Expires 来做为缓存判断的标准,HTTP1.1 则引入了更多的缓存控制策略例如 Entity tag,If-Unmodified-Since, If-Match, If-None-Match 等更多可供选择的缓存头来控制缓存策略。
  2. **带宽优化及网络连接的使用:**HTTP1.0 中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1 则在请求头引入了 range 头域,它允许只请求资源的某个部分,即返回码是 206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。
  3. **错误通知的管理:**在 HTTP1.1 中新增了 24 个错误状态响应码,如 409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
  4. **Host 头处理:**在 HTTP1.0 中认为每台服务器都绑定一个唯一的 IP 地址,因此,请求消息中的 URL 并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个 IP 地址。HTTP1.1 的请求消息和响应消息都应支持 Host 头域,且请求消息中如果没有 Host 头域会报告一个错误(400 Bad Request)。
  5. **长连接:**HTTP 1.1 支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个 TCP 连接上可以传送多个 HTTP 请求和响应,减少了建立和关闭连接的消耗和延迟,在 HTTP1.1 中默认开启 Connection: keep-alive,一定程度上弥补了 HTTP1.0 每次请求都要创建连接的缺点。以下是常见的 HTTP1.0:

区别用一张图来体现:

HTTP1.0 和 HTTP1.1的区别

HTTP1.0 和 1.1 现存的一些问题

  1. 上面提到过的,HTTP1.x 在传输数据时,每次都需要重新建立连接,无疑增加了大量的延迟时间,特别是在移动端更为突出。
  2. HTTP1.x 在传输数据时,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份,这在一定程度上无法保证数据的安全性。
  3. HTTP1.x 在使用时,header 里携带的内容过大,在一定程度上增加了传输的成本,并且每次请求 header 基本不怎么变化,尤其在移动端增加用户流量。
  4. 虽然 HTTP1.x 支持了 keep-alive,来弥补多次创建连接产生的延迟,但是 keep-alive 使用多了同样会给服务端带来大量的性能压力,并且对于单个文件被不断请求的服务(例如图片存放网站),keep-alive 可能会极大的影响性能,因为它在文件被请求之后还保持了不必要的连接很长时间。

HTTPS 应声而出

为了解决以上问题,网景在 1994 年创建了 HTTPS,并应用在网景导航者浏览器中。 最初,HTTPS 是与 SSL 一起使用的;在 SSL 逐渐演变到 TLS 时(其实两个是一个东西,只是名字不同而已),最新的 HTTPS 也由在 2000 年五月公布的 RFC 2818 正式确定下来。简单来说,HTTPS 就是安全版的 HTTP,并且由于当今时代对安全性要求更高,chrome 和 firefox 都大力支持网站使用 HTTPS,苹果也在 ios 10 系统中强制 app 使用 HTTPS 来传输数据,由此可见 HTTPS 势在必行。

HTTPS 与 HTT

  1. HTTPS 协议需要到 CA 申请证书,一般免费证书很少,需要交费。
  2. HTTP 协议运行在 TCP 之上,所有传输的内容都是明文,HTTPS 运行在 SSL/TLS 之上,SSL/TLS 运行在 TCP 之上,所有传输的内容都经过加密的。
  3. HTTP 和 HTTPS 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
  4. HTTPS 可以有效的防止运营商劫持,解决了防劫持的一个大问题。

HTTP 和 HTTPS

HTTPS 改造

如果一个网站要全站由 HTTP 替换成 HTTPS,可能需要关注以下几点:

  1. 安装 CA 证书,一般的证书都是需要收费的,这边推荐一个比较好的购买证书网站:1)Let's Encrypt,免费,快捷,支持多域名(不是通配符),三条命令即时签署+导出证书。缺点是暂时只有三个月有效期,到期需续签。2Comodo PositiveSSL,收费,但是比较稳定。
  2. 在购买证书之后,在证书提供的网站上配置自己的域名,将证书下载下来之后,配置自己的 web 服务器,同时进行代码改造。
  3. HTTPS 降低用户访问速度。SSL 握手,HTTPS 对速度会有一定程度的降低,但是只要经过合理优化和部署,HTTPS 对速度的影响完全可以接受。在很多场景下,HTTPS 速度完全不逊于 HTTP,如果使用 SPDY,HTTPS 的速度甚至还要比 HTTP 快。
  4. 相对于 HTTPS 降低访问速度,其实更需要关心的是服务器端的 CPU 压力,HTTPS 中大量的密钥算法计算,会消耗大量的 CPU 资源,只有足够的优化,HTTPS 的机器成本才不会明显增加。

推荐一则淘宝网改造 HTTPS的文章。

使用 SPDY 加快你的网站速度

2012 年 google 如一声惊雷提出了 SPDY 的方案,大家才开始从正面看待和解决老版本 HTTP 协议本身的问题,SPDY 可以说是综合了 HTTPS 和 HTTP 两者有点于一体的传输协议,主要解决:

  1. **降低延迟:**针对 HTTP 高延迟的问题,SPDY 优雅的采取了多路复用(multiplexing)。多路复用通过多个请求 stream 共享一个 tcp 连接的方式,解决了 HOL blocking 的问题,降低了延迟同时提高了带宽的利用率。
  2. **请求优先级(request prioritization):**多路复用带来一个新的问题是,在连接共享的基础之上有可能会导致关键请求被阻塞。SPDY 允许给每个 request 设置优先级,这样重要的请求就会优先得到响应。比如浏览器加载首页,首页的 html 内容应该优先展示,之后才是各种静态资源文件,脚本文件等加载,这样可以保证用户能第一时间看到网页内容。
  3. **header 压缩:**前面提到 HTTP1.x 的 header 很多时候都是重复多余的。选择合适的压缩算法可以减小包的大小和数量。
  4. **服务端推送(server push):**采用了 SPDY 的网页,例如我的网页有一个 sytle.css 的请求,在客户端收到 sytle.css 数据的同时,服务端会将 sytle.js 的文件推送给客户端,当客户端再次尝试获取 sytle.js 时就可以直接从缓存中获取到,不用再发请求了。

SPDY构成图

HTTP2.0 的前世今生

顾名思义有了 HTTP1.x,那么 HTTP2.0 也就顺理成章的出现了。HTTP2.0 可以说是 SPDY 的升级版(其实原本也是基于 SPDY 设计的),但是,HTTP2.0 跟 SPDY 仍有不同的地方,主要是以下两点:

  1. HTTP2.0 支持明文 HTTP 传输,而 SPDY 强制使用 HTTPS
  2. HTTP2.0 消息头的压缩算法采用 HPACK,而非 SPDY 采用的 DEFLATE

HTTP2.0 的新特性

  • **新的二进制格式(Binary Format):**HTTP1.x 的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认 0 和 1 的组合。基于这种考虑 HTTP2.0 的协议解析决定采用二进制格式,实现方便且健壮。
  • **多路复用(MultiPlexing):**即连接共享,即每一个 request 都是是用作连接共享机制的。一个 request 对应一个 id,这样一个连接上可以有多个 request,每个连接的 request 可以随机的混杂在一起,接收方可以根据 request 的 id 将 request 再归属到各自不同的服务端请求里面。

多路复用原理图

  • **header 压缩:**如上文中所言,对前面提到过 HTTP1.x 的 header 带有大量信息,而且每次都要重复发送,HTTP2.0 使用 encoder 来减少需要传输的 header 大小,通讯双方各自 cache 一份 header fields 表,既避免了重复 header 的传输,又减小了需要传输的大小。
  • **服务端推送(server push):**同 SPDY 一样,HTTP2.0 也具有 server push 功能。目前,有大多数网站已经启用 HTTP2.0,例如 YouTuBe,淘宝网等网站,利用 chrome 控制台可以查看是否启用 H2:

chrome控制台

更多关于 HTTP2 的问题可以参考:HTTP2 奇妙日常,以及 HTTP/2 官网

HTTP2.0 的升级改造

对比 HTTPS 的升级改造,HTTP2.0 或许会稍微简单一些,你可能需要关注以下问题:

  1. 前文说了 HTTP2.0 其实可以支持非 HTTPS 的,但是现在主流的浏览器像 chrome,firefox 表示还是只支持基于 TLS 部署的 HTTP2.0 协议,所以要想升级成 HTTP2.0 还是先升级 HTTPS 为好。
  2. 当你的网站已经升级 HTTPS 之后,那么升级 HTTP2.0 就简单很多,如果你使用 NGINX,只要在配置文件中启动相应的协议就可以了,可以参考 NGINX 白皮书NGINX 配置 HTTP2.0 官方指南
  3. 使用了 HTTP2.0 那么,原本的 HTTP1.x 怎么办,这个问题其实不用担心,HTTP2.0 完全兼容 HTTP1.x 的语义,对于不支持 HTTP2.0 的浏览器,NGINX 会自动向下兼容的。

后记

  • 以上就是关于 HTTP,HTTP2.0,SPDY,HTTPS 的一些基本理论,有些内容没有深入讲解,大家可以跟进参考连接具体查看。
  • 关于 HTTP1.x 的一些优化方式,例如文件合并压缩,资源 cdn,js,css 优化等等同样使用与 HTTP2.0 和 HTTPS,所以 web 前端的优化,还是要继续进行。
  • 其实 WEB 发展如此迅速的今天,有些技术是真的要与时俱进的,就像苹果宣布 ios 10 必须使用 HTTPS 开始,关于 web 协议革新就已经开始了,为了更好的性能,更优越的方式,现在就开始升级改造吧

HTTP/2 搭建

正如上面后记所说,开始改造吧!我改造的网站是我的个人网站。

  • **下载 SSL 证书:**我的域名是在阿里云购买的,登入阿里云后台进入域名基本信息查看,就能看到免费开启 SSL 证书,如果你有钱可以选择第一个,作为穷逼一枚,当然是选择免费的证书啦。
    按照操作一步一步走,然后,然后你就得到一个免费的 SSL 证书啦。

SSL 证书
SSL 证书

  • **配置 HTTPS 和 HTTP2:**下面就开始配置 NGINX 了,先附上一篇 NGINX https帮组文档
    • 将下载的 SSL 放在服务器的目录中,可以根据个人习惯放入目录,得方便找到
    • 配置 nginx,进行 nginx 配置和重定向之后,进行 nginx 重启(nginx -s reload),下面就是见证奇迹的时刻了。需要注意的一点,如果出现警告,请把 SSL on 这行注释掉就 OK 了。

SSL 证书放置
NGINX 配置

  • **验证 HTTPS 和 HTTP2:**nginx 重启之后,应该 ok 了,但是应该如何去验证呢,下面有两个方法

    1. 在控制台输入 window.chrome.loadTimes() 查看信息
    2. 安装 chrome 插件HTTP/2 and SPDY indicator进行查看。

window.chrome.loadTimes()查看
安装插件 HTTP/2 and SPDY indicator
查看是启用HTTP/2

总结

至此 HTTP/2 的学习和搭建就完成,前端还有很多的优化内容要学习和去时间,优化不息,学习不止,感谢阅读!

到此结束

本文地址:HTTP 2.0 初体验,更多信息可以访问我的个人网站,说不定有您想看的