用 Nginx 如何启用编译配置 HTTP/2 支持的最实用教程

HTTP/2(超文本传输协议第2版,最初命名为 HTTP 2.0),是在 Google 之前提出的 SPDY 协议的基础上演变而来,相对 HTTP1.1 增加了连接复用、头部压缩、服务端 push 等特性。与 HTTP1.1 完全语义兼容,几乎可以无缝升级。目前主流浏览器都已经支持 HTTP/2 了(IE 自 IE 11 开始支持)。

HTTP/2的主要优势:

  • 使用二进制数据(不像HTTP/1.1一样使用明文)而且它使用了header数据压缩。不用再为header和cookie的大小而担心了。
  • 它是完全多元化的,为了提升并发性可以使用一个连接加载多种资源。你的网站性能在需要引入多种资源的时候会表现得更好,因为现在它们可以在一次TCP连接中全部加载,在非阻塞模式中。域名切分和资源级联变成了反面模式。简单来说:你的网站加载会更快。
  • 它允许服务器提前推送请求到客户端的缓存(目前Ngnix不支持这个特性)
  • 它使用新的ALPN扩展,那将允许更快地加密连接。这个加密协议在初始化连接的阶段是可用的。

Web 服务器

说明

默认编译的 Nginx 并不包含 h2 模块,我们需要加入参数来编译,**截止发文**,Nginx 1.9 开发版及以上版本源码需要自己加入编译参数,从软件源仓库下载的则默认编译。 Tengine 可以同时部署 h2 和 SPDY 保证兼容性,Nginx 则是一刀切不再支持 SPDY。

安装/编译

如果你编译的 Nginx 不支持,那么在 ./configure 中加入:--with-http_v2_module ,如果没有 SSL 支持,还需要加入 --with-http_ssl_module

然后 make && make install 即可。

开源版本的 Nginx 从 1.9.5 版开始支持 HTTP/2,其实配置也很简单,升级 Nginx 到最新版本,然后把之前 HTTPS 配置中的 spdy 改成 http2 就行了(listen 443 sslhttp2 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。

你需要检测一下你的OpenSSL版本,方法如下:

openssl version

如果版本不够高,请从官网下载,然后在编译nginx的时候,加上

--with-openssl=<open ssl source directory>

注意上面是源码文件夹。

配置是很简单的, 用 nginx 如何启用 HTTP/2 支持?

答:很简单,只需编译安装最新版 Nginx,并在配置中启用:

server {
    listen 443 ssl http2 default_server;

    ssl_certificate    server.crt;
    ssl_certificate_key server.key;
    ...
}

就可以支持HTTP2了。

如果你开了

ssl_prefer_server_ciphers  on;

那就要注意你的 ssl_ciphers 配置不要在HTTP2的黑名单里,不然你可能会遇到Chrome浏览器报错 ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY 。 SE上的一个问题也详细解释了这个现象。

知道原因就好办了,先升级本地的 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 已经开启成功了。

2016-05-21_233215

当然如果你是 ubuntu 16.04,就没有那么麻烦了,直接安装 Nginx 配置一下就行:https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-with-http-2-support-on-ubuntu-16-04

 

Top Down