原文链接:http://wetest.qq.com/lab/view/313.html
商业转载请联系腾讯 WeTest 获得授权,非商业转载请注明出处。
自从去年 QQ 空间移动端页面开始切换到 HTTPS 之后,页面性能遇到了比较大的挑战,HTTPS 对页面访问速度带来了比较大的影响,所以我们通过实践总结了一些能够提升 HTTPS 页面访问速度的方法,这些数据都是我们和 STGW 的同事反复实验、多次分析所得到的,希望能够减少大家对于全站启用 HTTPS 的顾虑。我们的目的是,在不影响用户体验的情况下,竭尽全力保护用户的信息安全!
页面在切到 HTTPS 之前,iOS 的访问速度约为 1795ms,切到 HTTPS 之后,iOS 的访问速度直接飙到 2630ms,我的天呐,上涨了 900ms,接近 50%,吓得我赶紧把入口又切回了 HTTP。之后,便开始踏上了提升 HTTPS 访问速度的道路。(文章里的数据以 iOS 为例,访问速度指的是页面 html 开始请求到页面 js 执行完毕的耗时)。先简单以图示总结下我们优化的结论:
使用 SPDY 协议是我们优化的第一步,SPDY(speedy)是 Google 很早就提出的协议,通过多路复用、请求优先级以及 HTTP 报头压缩,来提升页面的访问速度。但是公司貌似没有一个统一的平台支持 SPDY,在寻求了 TEG 小伙伴的帮助之后,他们首次支持了 SPDY。SPDY 在 iOS 的兼容性比较好,iOS 8.0 以上的 safari 和 webview 都支持,覆盖了 Qzone 85% 以上的 iOS 用户。所以决定开启 HTTPS+SPDY 试试效果。开启 SPDY 之后的页面访问速度提升了 370ms,已经非常不错了。(在 SPDY 的兼容性上,iOS 大部分都支持了,而安卓 tbs 内核支持 SPDY 的版本也正在灰度当中,全量之后预计也能覆盖 80% 的 Qzone 用户。)
根据第一次 SPDY 的尝试,HTTPS 的访问速度有了 300 多毫秒的提升,但跟 HTTP 相比差距还是有 400ms 的差距,分析了一下,这 400ms 的差距主要是来自于 SSL 握手的耗时,根据 SPDY 协议,每个域名建立一个 TCP 连接,各自要进行一次 SSL 握手,每次耗时约 200ms,页面一共有两个关键域名,所以 HTTPS+SPDY 一共比 HTTP 慢了 400ms。根据这个分析结果,我们也有了进一步的优化方向,那就是减少 SSL 的耗时。
减少 SSL 握手的耗时,可以有三个方式:
(1)提升 TCP 连接的复用率;
(2)提升 SSL session 的复用率;
(3)减少页面上的域名。
对于提升 TCP 连接的复用率,我们想了一个方法,在页面的入口处预建了一个连接,在用户点击入口之前,先向 h5.qzone.qq.com(页面的域名)发起一个 https 请求,可以请求一个返回内容为空的 url。同时,服务器端要开启 keep alive, keep alive 的时间也并不是越长越好,我们使用的是 60 秒。这个预建的连接,不止减少了 SSL 握手的耗时,实际上同时也节省了 TCP 建立连接的时间。根据我们的实践数据,在预建连接之后,页面的访问速度又提升了 400ms。其中,TCP 连接复用的命中率大约是 75%。
对于提升 SSL session 复用率,需要服务器端支持 session ticket 或者 session cache,目前我们的 STGW 是支持了分布式 session cache 和全局 session ticket key。需要说明一下的是,如果我们前面做了预建连接,复用了 TCP 连接的请求不会再发生 SSL 握手,也就不需要 session 复用。不过还是分享下我们 SSL session 复用的实践数据。SSL session 复用对大部分安卓用户的提升非常明显,可以把 SSL 握手耗时从之前的 400ms 优化到 100 多 ms。而对于 iOS,由于本身机器性能更好,SSL 握手时间的耗时本身就比安卓用户少,从之前的 200ms 优化到 100ms,提升了 50%,并且 iOS 由于不支持 session ticket,只能使用 session cache,复用率比较低。SSL seesion 总体的复用率大约是 40%。
对于减少页面上的域名,前面说到页面有两个关键域名,一个是 h5.qzone.qq.com,一个是 cdn 域名 qzonestyle.gtimg.cn。每个域名的 SSL 握手各多耗时 200ms,所以另一个优化的方式就是域名收归,把页面收归到只有一个域名,减少一次 SSL 握手的耗时。于是我们把页面上 qzonestyle.gtimg.cn 的 js 通过代理的方式也收归到 h5.qzone.qq.com,使这个页面只有一个关键域名,而 h5.qzone.qq.com 在入口页面已经做了预建连接,最大程度减少了 TCP 和 SSL 的时间。域名收归后,页面的访问速度提升了 200ms。这种代理收归的方式,也有另一个好处,Qzone 由于业务复杂,域名非常多,通过中间层代理收归域名,再转发到各个业务,这样切换 HTTPS 对各个业务都是透明的,可以说大大降低了我们全站切换到 HTTPS 的开发成本。
推荐使用的 TLS 协议和 cipher suite,在协议和算法层面,我们也做了一些统计来进行对比。在 HTTPS 握手过程中记录协议类型、加密套件、握手时间,并且将上述内容返回给页面。页面在记录用户的访问速度之后,上报数据的同时,把上述的协议类型等数据也一同上报。
从上表可以看出来,TLS1.2 协议的性能要明显优于 1.1 和 1.0。Cipher suite 方面,ECDHE-RSA-AES128-GCM-SHA256 和 ECDHE-RSA-AES128-SHA256 性能最好。ECDHE-RSA-CHACHA20-POLY1305 理论上讲对性能提升有较大帮助,但是由于 iOS 不支持该类算法,所以从数据样本上无法体现优势。除了上面所列出来的,后续我们依然会进行协议和算法层面的更多性能分析和优化,包括 TCP 参数调优,握手过程优化,SSL record size 适配等。
做了以上这些优化之后,HTTPS 的页面访问速度提升了 1000+ms,相比 HTTP,差距已经非常小了。由于 TCP 复用,甚至比之前的访问速度还要快。同时,我们还在马不停蹄地做更多的尝试,比如开始写这篇文章的时候还在用 SPDY,写到结尾的时候我们已经启用了 HTTP/2(喂,难道不是因为作者是拖延症患者吗?!)亲,你还有什么理由再不启用 HTTPS?
下面,我们来看一下如何测试 HTTPS 页面优化结果
1)点击进入压测大师产品首页(http://wetest.qq.com/gaps/ )开通项目,创建测试,点击进入 URL 测试。名称和描述可以自己填写。(图中示例起始人数 50 人,每隔 60 秒增加 50 人,加到 200 人为上限)
输入合适的测试标题和测试设置
(此图为动图,横屏观看效果更佳)
2)新建一个客户端请求,接口压测包括读写接口,读接口基本是 GET 请求,写接口基本是 POST 请求。GET 请求使用 url 请求参数,填写测试用例的基础数值,选择正确的 URL
配置页面 header 信息
3)随后进行 Header 的配置,Header 的名称在选定 URL 的内,打开 URL 的链接(推荐使用 chrome 浏览器),敲击 F12 并刷新页面,选定 Network-Name-Headers-Request Headers(Header 的名称与值均在内查看,如下图所示)
查看页面 header 信息
到这里,基本就完成了对 https 的配置过程了,是不是很简单?下面动图可以再回顾一下操作的流程:
gif 动态图展示操作的流程
(此图为动图,横屏观看效果更佳)
WeTest 压测大师运用了沉淀十多年的内部实践经验总结,通过基于真实业务场景和用户行为进行压力测试,帮助游戏开发者发现服务器端的性能瓶颈,进行针对性的性能调优,降低服务器采购和维护成本,提高用户留存和转化率。
功能目前免费对外开放中,点击http://wetest.qq.com/gaps 即可体验!
如果对使用当中有任何疑问,欢迎联系腾讯 WeTest 企业 qq:800024531