HTTP/2(超文本传输协议第2版,最初命名为 HTTP 2.0),是在 Google 之前提出的 SPDY 协议的基础上演变而来,相对 HTTP1.1 增加了连接复用、头部压缩、服务端 push 等特性。与 HTTP1.1 完全语义兼容,几乎可以无缝升级。目前主流浏览器都已经支持 HTTP/2 了(IE 自 IE 11 开始支持)。
开源版本的 Nginx 从 1.9.5 版开始支持 HTTP/2,其实配置也很简单,升级 Nginx 到最新版本,然后把之前 HTTPS 配置中的 spdy
改成 http2
就行了(listen 443 ssl http2 default_server),但改了之后发现并没有生效,直接退回到了 HTTP1.1。nginx -V
查看编译参数也带有 --with-http_v2_module
,应该没什么问题才对。Google 了一把发现是 OpenSSL 版本的问题,我使用的是 ubuntu 14.04 下的 ppa:nginx/stable 源,这个源上的 Nginx 是在 OpenSSL 1.0.1f 上编译而成的,而 OpenSSL 的这个版本不支持 ALPN,所以无法开启 HTTP/2。
Note that accepting HTTP/2 connections over TLS requires the “Application-Layer Protocol Negotiation” (ALPN) TLS extension support, which is available only since OpenSSL version 1.0.2. Using the “Next Protocol Negotiation” (NPN) TLS extension for this purpose (available since OpenSSL version 1.0.1) is not guaranteed.
知道原因就好办了,先升级本地的 OpenSSL到最新版:
1 2 |
$ openssl version OpenSSL 1.0.2h 3 May 2016 |
然后替换 Nginx 源为 ppa:ondrej/nginx 重新安装 Nginx:
1 2 3 4 5 6 7 8 9 |
$ sudo add-apt-repository --remove ppa:nginx/stable $ sudo add-apt-repository ppa:ondrej/nginx $ sudo apt-get update $ sudo apt-get install -f nginx nginx-common nginx-full $ nginx -V nginx version: nginx/1.10.0 built with OpenSSL 1.0.2g 1 Mar 2016 (running with OpenSSL 1.0.2h 3 May 2016) TLS SNI support enabled |
现在再打开网站,发现 HTTP/2 已经开启成功了。
当然如果你是 ubuntu 16.04,就没有那么麻烦了,直接安装 Nginx 配置一下就行:https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-with-http-2-support-on-ubuntu-16-04
推荐阅读:
Dropbox 迁移到 HTTP/2 的经验,满满都是干货:https://dropbox.tech/infrastructure/enabling-http2-for-dropbox-web-services-experiences-and-observations
检查网站是否支持 SPDY 或者 HTTP/2 的 Chrome 扩展:HTTP/2 and SPDY indicator
参考资料:
https://www.nginx.com/blog/nginx-1-9-5/
https://serverfault.com/questions/732474/nginx-configured-with-http2-doesnt-deliver-http-2
https://nginx.org/en/docs/http/ngx_http_v2_module.html
为什么我们应该尽快支持 ALPN?https://imququ.com/post/enable-alpn-asap.html