HTTP/2升级小记

最近H5被插广告愈演愈烈,于是打算给H5增加HTTPS支持。既然都支持了HTTPS,那么HTTP/2也就顺便来支持一下好了,反正SSL证书已经不是问题了。

我们是全容器环境,包括前端机在内,全部跑在容器里,更新前端nginx容器配置即可。Nginx从1.9.5版本开始支持HTTP/2的,查了一下满足条件。从HTTPS到HTTP/2,只需要:

即可。

但是会有一些问题。协议协商包括NPN和ALPN两种,NPN是SPDY时代的产物,HTTP/2定稿时已经被ALPN取代。我们的目标是支持HTTP/2,因此务必支持ALPN。

关于NPN和ALPN的区别,可以参考这篇文章:《为什么我们应该尽快支持 ALPN?》我引用其中的梗概描述:

NPN(Next Protocol Negotiation,下一代协议协商),是一个 TLS 扩展,由 Google 在开发 SPDY 协议时提出。随着 SPDY 被 HTTP/2 取代,NPN 也被修订为 ALPN(Application Layer Protocol Negotiation,应用层协议协商)。二者目标一致,但实现细节不一样,相互不兼容。以下是它们主要差别:

  • NPN 是服务端发送所支持的 HTTP 协议列表,由客户端选择;而 ALPN 是客户端发送所支持的 HTTP 协议列表,由服务端选择;
  • NPN 的协商结果是在 Change Cipher Spec 之后加密发送给服务端;而 ALPN 的协商结果是通过 Server Hello 明文发给客户端;

需要注意的是,OpenSSL 1.0.2 才开始支持 ALPN。因此需要升级OpenSSL才可以。

由于OpenSSL是系统广泛依赖的基础库,不可贸然升级,对于我们来说,只需要选择合适的Nginx容器镜像即可。

目前官方的Nginx镜像维护了这些版本:

latest, 1, 1.11, 1.11.1 (mainline/jessie/Dockerfile)
stable, 1.10, 1.10.1 (stable/jessie/Dockerfile)
mainline-alpine, alpine, 1-alpine, 1.11-alpine, 1.11.1-alpine (mainline/alpine/Dockerfile)
stable-alpine, 1.10-alpine, 1.10.1-alpine (stable/alpine/Dockerfile)

Alpine的软件包一向更新迅速,nginx镜像基于alpine的3.3版本构建,使用的OpenSSL是1.0.2h-r1,满足要求。于是升级容器镜像为nginx:alpine。

重启之后Chrome和Safari可以正常通过HTTP/2访问了,但是Firefox却不行,打不开网页,也并没有报错。于是使用SSL诊断工具,看一下情况:

在Firefox 46 / Win 7一项中,显示:

Server negotiated HTTP/2 with blacklisted suite RSA 2048 (SHA256)

在Firefox的官方社区,找到了这个问题:

然而并没有人回复,原作者选择降级回http/1.1回避了这个问题。于是打算一探究竟,爆栈网的回答多半指向使用了不安全的加密选项,于是开始尝试调整加密选项。

这篇文章给了一个很好的建议:

把Nginx的ciphers设为:

重载配置之后解决,现在绝大多数支持HTTP/2的浏览器,都可以通过HTTP/2来访问了。

那么切换到HTTP/2之后性能提升了多少呢?我暂时还没有做数据的对比测试,主观感受H5在浏览器中打开的速度明显加快了,尤其是第二页打开时间,几乎是秒开。有时间的话,我再做客观数据的对比分析吧。

升级过程中的一些小Tips:

  • Chrome可以通过chrome://net-internals/#http2来观察当前HTTP2的连接情况,控制台默认不显示网络通讯的协议,可以在列头上右键选择Protocol来显示。HTTP/2协议显示为h2。
  • 如果静态资源是在CDN上的,那么CDN也支持http2才是最好的。我们目前使用阿里云CDN,只要配置了SSL证书,就默认支持HTTP/2。

一些参考文章:

HTTP/2升级小记》上有1条评论

评论已关闭。