Nginx 通过 Nginx 启用 HTTP/2

huacnlee · 2016年04月29日 · 最后由 steveltn 回复于 2016年05月10日 · 13016 次阅读

HTTP/2 发布已经有一段时间了,你想让你的网站也开启么?

HTTP/2 给我们带来什么?

阅读:http://www.infoq.com/cn/news/2014/02/http-2

开启了 HTTP/2 以后,低版本浏览器是否能用?

没问题!Nginx 会自动向下兼容 HTTP 1.1,如果客户端不支持 HTTP/2

以及浏览器支持列表:http://caniuse.com/#feat=http2

如何在 Nginx 上面启用 HTTP/2

你需要升级 Nginx 到 1.9.5 以上的版本,安装方法可以参考:install_nginx

如果你是 Ubuntu Server 可以直接用我打包好的流程直接安装:

$ curl -sSL https://git.io/vVHhf | bash
$ nginx -v
nginx version: nginx/1.10.0

然后修改 Nginx 配置:

server {
  listen 443 ssl http2;
  ...
}

然后保存,重启 Nginx

$ sudo service nginx reload

注意:HTTP/2 得在 HTTPS 下面工作,虽然 HTTP/2 本身可以在非 HTTPS 下面工作,但目前还没有浏览器支持!

然后 Chrome 开发者工具可以看到效果:

也可以用 Chrome 访问:chrome://net-internals/#http2 查看

更多阅读

一直感觉通过 Nginx 启用的 HTTP2 不是真正的 HTTP2,HTTP2 的重要功能都没办法用到。

Ruby China 就是潮,但 HTTP2 貌似 h20 更有前途,有没有想法试试呢 https://h2o.examp1e.net/

注意:HTTP/2 得在 HTTPS 下面工作,虽然 HTTP/2 本身可以在非 HTTPS 下面工作,但目前还没有浏览器支持!

是说目前用 HTTP2 的前提是必须全站 HTTPS 吗?

Ruby China 终于跟进了

#3 楼 @hooopo

http://caniuse.com/#feat=http2

2.Only supports HTTP2 over TLS (https)

上面显示也是这么说的

@huacnlee http://railscasts-china.com/ 请问一直无法访问,是什么原因啊,以前还可以的

#1 楼 @ibachue 然而总比全部功能都没办法用到要好。 至少你有脑袋压缩功能了。

然而 Rails 和 nginx 之间还是 HTTP/1.1

没问题!Nginx 会自动向下兼容 HTTP 1.1,如果客户端不支持 HTTP/2

以及浏览器支持列表:http://caniuse.com/#feat=http2

这是机器翻译的?

#1 楼 @ibachue 很同意,感觉现在基于 Rack 的部署方式就没办法真正用到 HTTP/2 的好处,这样的话还不如只用 HTTP/1.1,部署起来还更简洁。

目前看个人觉得可能只有 OpenResty 或者 h2o 这种把语言嵌入到 HTTP 服务器中,配合 fiber 实现之后,才有可能把 HTTP/2 的好处发挥出来,但是那样就需要全新的 API 而不能是现在的 Rack 了。

#8 楼 @steveltn

然而 Rails 和 nginx 之间还是 HTTP/1.1

这个就是回答

HTTP/2 的功能远远多于 1.1,因此 Rails 不为 HTTP/2 做优化,或者你的应用不为 HTTP/2 做优化,就不能被认为是真正用了 HTTP/2(还增加各种调试负担和测试负担)。

为啥我的 F12 里面的 network 下面没有 Protocol 这一项呢

#14 楼 @hxh1246996371 右键菜单里面启用

终于启用成功了 https://www.awesomes.cn。 需要注意的几个点是,我是 nginx+passenger,升级 nginx 的时候执行楼主的代码貌似没用,需要先下载最新 nginx 源码,然后指定文件位置: passenger-install-nginx-module --nginx-source-dir=./nginx-1.9.15,然后在安装过程中,需要添加额外参数 --with-http_v2_module --with-http_ssl_module --with-openssl=/path/to/openssl

#17 楼 @hxh1246996371 哪当然了,我上面的内容是安装默认的 Nginx 内容。

Passenger 是三方 module

#13 楼 @ibachue

这些优化是指什么呢? HTTP2 的主要优点不就是可以把多个请求放在一个 TCP connection 中,并且提供压缩么?这并不需要 app 端做任何改变,Nginx 里 enable 不就行了?

#19 楼 @steveltn 主要体现在两点,1. 现有的诸多基于 HTTP/1.1 而设计的优化特性必须被废除,在 HTTP/2 下,它们不仅起不到优化的作用,反而还在帮倒忙,一个显而易见的例子就是 Assets Pipeline,还有例如于将多个图标合成一张图片的技术,长链接也是。2. 另外就是 HTTP/2 的 Server Push,需要 app 端主动告知服务器端即将推送给客户端的数据。

#20 楼 @ibachue 部分 assets pipeline 的功能和 sprites 不再需要了,但是我不觉得留着它们会帮倒忙。 Server push 可以先不用。

我认为 HTTP/2 主要的功能:压缩和节省 TCP 通道的作用是可以马上使用的。我试验下来在 Nginx 上启用 HTTP/2 后速度提升立竿见影。

至于 Rails 和 Nginx 之间的通信还是 HTTP 1.1,本来在同一主机上 TCP 握手就很快,性能瓶颈不在这里。

#21 楼 @steveltn 帮倒忙是指,本来将所有资源打包在一起就是因为建立 HTTP/1.1 新连接效率低下,一旦用 HTTP/2 就没有这个问题,反而打包的两个缺陷体现了出来,一个是明明暂时不需要用到的资源也被下载,浪费了网络,二是缓存颗粒度变大,命中率下降。 如果不用 Assets Pipeline(的打包特性),前端的代码就要发生变化,比如说应该使用 requirejs 这样的库来并发加载大量小型 JS 文件,Rails 也应该对此提供 helper。 Server Push 不用,HTTP/2 就有一半好处你没有体会到了。

#22 楼 @ibachue 如果在 HTTP/2 下,加载大量小文件所花的时间开销很小,可以忽略的话,那么为什么还需要用 server push 把这些文件预先 push 过来呢?

#23 楼 @steveltn 加载小文件的时间开销不止有传输时间啊 HTML 传输过来以后要解析,才能获取到要加载的小文件的地址,JS 可能还要执行才能获取到依赖的其它 JS 文件的地址,服务器收到了静态文件的请求也要处理,这些都要时间啊。如果他们还在解析的时候,所有的文件就已经主动推送完毕了,不是就节省了很多时间嘛。

Assets Pipeline 是一个接口,可以接入各种预处理程序,包括打包也只是其中一个预处理程序。开发模式下默认把打包给关了,不就可以利用 server push 了嘛。

#24 楼 @ibachue 那如果用 requirejs 加载大量小型 js 文件难道不需要吗?Asset pipeline 的打包不是可以节省这部分时间么? 虽然有 overhead,但统计上并不严重。

#26 楼 @steveltn 确实不需要啊。HTTP/2 最大的特点就在于 在这个协议下,大量单个小文件和一个大文件在传输时负载没什么区别,但是大量小文件 cache 容易,开发也方便,不需要加载暂时用不到的文件,所以优势就体现出来了。

#27 楼 @ibachue 可能是我理解不对,但是你这句话和你上一条回复好像矛盾了。 所以,在 HTTP/2 下,多次请求小文件(不用 server push)到底是不是比一次请求大文件更耗时?

我认为是这样的,HTTP/2 下,多次请求小文件也是更耗时的。对此,比较优秀的解决方法是用 server push。但是如果 app 端还不支持,用 assets pipeline 打包也比什么都不做好。启用 Nginx 上的 HTTP/2 只需要改动两三行 Nginx 配置,是目前最方便的提升性能的方法。而且在这种状态下,assets pipeline 打包依然比不打好。以后如果方便或有精力,当然可以换掉 assets pipeline 的打包,换用 server push。

#28 楼 @steveltn

所以,在 HTTP/2 下,多次请求小文件(不用 server push)到底是不是比一次请求大文件更耗时?

在不考虑缓存的情况,也不考虑是否将不需要的文件打包进大文件的情况,也不考虑服务器处理的情况下,多次请求小文件和一次请求大文件的耗时在 HTTP/2 下应该是差不多的(小文件可能是差点,比如需要更多的发送 header,gzip 压缩多个小文件也不如压缩一个大文件,但这些差距应该不明显)。但是如果考虑进这些情况(即使没有 server push),我认为多次请求小文件在 HTTP/2 下优势明显,毕竟传输数据量减小,服务器虽然要处理多个请求,但是那些请求完全可以并发处理(HTTP/2 能在单连接的情况下并发大量请求),所以并不会消耗更多时间。

总的来说我的意思就是“通过 Nginx 就可以启用 HTTP / 2”是不够的,只能说看上去有点像,速度会有所提升,但是依然没有到达 HTTP/2 所能达到的高度(就像国内的 4G 网络,其实也没达到 4G 的网络的标准,比之前的 3G 肯定是快了很多,但依然不是真正的 4G,就酱)。

#29 楼 @ibachue

我的意思是如果“多次请求小文件和一次请求大文件的耗时在 HTTP/2 (without out server push) 下应该是差不多的”,那么通过 server push 来减少 request 数量的提升就不明显。因为 server push 实际上就相当于一个更聪明、粒度更细的、缓存 overhead 比较小的把多个小 request 合并成一个大 request 的方法。

我的观点 Nginx 启用的 HTTP/2 虽然没有达到 HTTP/2 的最大性能,但是以最小的配置达到了显著的性能提升,比没有强。

Chrome 下似乎是有点问题的,我一旦开启 HTTP2,chrome 就会显示改网页已被永久移除。Safari 下倒是正常

#31 楼 @steveltn 我认为你对 server push 理解有误,assets pipeline 是将多个 response 内容合并为一个 response 发出,response body 在没有完全下载完毕前无法使用。而 server push 是将多个 response 一起返回,只要一个 response 下载完毕,其 body 部分就已经可以处理,其它部分继续下载即可。所以只要当 html 部分下载后,浏览器就可以开始处理,当处理完毕后准备下载 JS 和 CSS 文件的时候,这些文件都差不多已经下载完毕了。这使得 server push 的效率可以大幅领先。

你后面的观点不是和我一样嘛。

#33 楼 @ibachue 哦,我没想到这一层。server push 实际上做到了下载和处理的并行化,这点打包是做不到的。 我明白你的观点,但你字里行间让我感觉你认为不完全的 HTTP/2 开启了没有意义,这是我表示反对的地方。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号