提升HTTP/2性能的7个技巧

NGINX | 2015年10月26日

要进一步了解HTTP/2,请观看我们广受欢迎的网络研讨会录像:HTTP/2有哪些新变化?

历史悠久的超文本传输协议(即HTTP)标准现已更新。HTTP/2标准于2015年5月获批,目前正在浏览器和Web服务器(包括NGINX Plus和NGINX Open Source)中实施。目前,正在使用的所有Web浏览器中,近三分之二支持HTTP/2,而且这一比例每月增长数个百分点。

HTTP/2基于Google的SPDY协议构建。在Google Chrome浏览器停止支持SPDY之前,SPDY仍可作为一种选择,具体支持将于2016年初结束。NGINX率先支持SPDY,如今也在积极推动HTTP/2。我们的综合白皮书《面向Web应用开发者的HTTP/2》(PDF)介绍了HTTP/2及其如何基于SPDY构建,并说明了如何实施HTTP/2。

HTTP/2的主要功能与SPDY相同:

  • HTTP/2是一种二进制协议,而非文本协议,因此更加紧凑、高效
  • 每个域使用一个多路复用连接,而不是使用多个连接分别传输单个文件
  • 标头使用专门设计的HPACK协议进行压缩(而不是像SPDY那样使用gzip)
  • HTTP/2采用复杂的优先级机制,帮助浏览器优先请求最需要的文件。NGINX完全支持该机制(SPDY采用的机制较为简单)

现在需要决定是否采用HTTP/2,其中一项重要考量是如何充分发挥其优势。本篇博文将介绍决策和实施过程中与性能相关的注意事项。请查看以下7条HTTP/2性能优化建议:

  1. 确定目前是否需要HTTP/2
  2. 终止HTTP/2和TLS连接
  3. 考虑从SPDY入手
  4. 识别代码中针对HTTP/1.x的优化
  5. 实施HTTP/2或SPDY
  6. 修订HTTP/1.x优化
  7. 实施智能分片

注意:严格来说,SPDY和HTTP/2都不要求使用TLS,但二者主要在与SSL/TLS配合使用时才能发挥优势,而且浏览器仅在使用SSL/TLS时才支持SPDY或HTTP/2。

技巧 1:确定目前是否需要HTTP/2

实施HTTP/2并不复杂,正如我们在白皮书《面向Web应用开发人员的HTTP/2》(PDF)中所述。不过,HTTP/2并非万能之策;它对某些Web应用很有用,但对其他应用的作用则较为有限。

如果使用SSL/TLS(下文简称TLS),采用HTTP/2可能会提升网站性能。但如果尚未使用,则需要先添加TLS支持,才能使用HTTP/2。在这种情况下,使用TLS造成的性能损失预计会与使用HTTP/2带来的性能提升大致抵消。不过,在决定实施之前,请先测试这是否确实适用于您的网站。

HTTP/2有以下五项主要潜在优势:

  1. 每台服务器仅使用一个连接:HTTP/2对每台服务器使用一个连接,而不是每次请求文件都建立一个连接。这大幅减少了耗时的连接建立操作,对TLS尤其有利,因为建立TLS连接特别耗时。
  2. 提升TLS性能:HTTP/2只需执行一次耗时的TLS握手,多路复用则可充分利用这一条连接。HTTP/2还会压缩标头数据;不再采用文件合并等HTTP/1.x性能优化方式,也能让缓存更高效地发挥作用。
  3. 简化Web应用:借助HTTP/2,可以不再采用HTTP/1.x的“优化”方法,避免增加应用开发者和客户端设备的负担。
  4. 非常适合混合内容网页,HTTP/2非常适合包含HTML、CSS、JavaScript代码、图像和少量多媒体内容的传统网页。浏览器可以优先处理文件请求,让页面的关键部分更快显示。
  5. 支持增强安全性:通过降低TLS对性能的影响,HTTP/2让更多Web应用能够使用TLS,从而为用户提供更强的安全保障。

以下是您会遇到的五个相应弊端:

  1. 单一连接的开销更大:HPACK数据压缩算法会更新连接两端的查找表,使连接具有状态,因此单一连接需要额外的内存。
  2. 可能不需要加密,如果数据无需保护,或已受DRM或其他编码方式保护,TLS安全机制可能不会带来太大帮助。
  3. HTTP/1.x优化会适得其反:HTTP/1.x优化实际上会降低支持HTTP/2的浏览器的性能,而撤销这些优化还会增加额外工作。
  4. 大型下载无法从中受益:如果Web应用主要提供大型可下载文件或媒体流,可能不需要TLS;而且仅使用一个流时,多路复用也无法带来任何益处。
  5. 您的客户可能并不在意,也许您认为,客户并不在意他们在您网站上分享的猫咪视频是否受到TLS和HTTP/2保护,而您的判断可能是对的。

归根结底,关键在于性能。在这方面,既有好消息,也有坏消息。

好消息是,NGINX开展的一项初步内部测试得出了符合理论预期的结果:对于通过具有典型互联网延迟的连接请求的混合内容网页,HTTP/2的性能优于HTTP/1.x和HTTPS。根据连接的典型往返时间(RTT),测试结果分为三组:

  • 极低的RTT(0–20 ms),HTTP/1.x、HTTP/2和HTTPS之间几乎没有差异。
  • 典型互联网RTT(30–250 ms):HTTP/2比HTTP/1.x更快,而两者都比HTTPS更快。美国相邻城市之间的RTT约为30 ms,横跨美国东西海岸(约3,000英里)的RTT约为70 ms。东京与伦敦之间最短路线的RTT约为240 ms。
  • 较高的RTT(300 ms及以上),HTTP/1.x比HTTP/2更快,而HTTP/2又比HTTPS更快。

该图显示了首次绘制时间,即用户首次在屏幕上看到网页内容所需的时间。通常认为,这项指标对用户感知网站的响应速度至关重要。

有关测试的详细信息,请观看我在nginx.conf 2015上的演讲《NGINX中的HTTP/2模块》。

不过,每个网页都不尽相同,实际上每个用户会话也各有差异。如果您提供流媒体或大型可下载文件,或者已经把HTTP/1.x优化研究得,呃,榨不出一点“糖分”了(借用一下《火星救援》中的说法),结果可能会有所不同,甚至完全相反。

总而言之,您可能会发现成本与收益之间的权衡并不明确。如果是这样,请尽可能多地了解相关信息,对自己的内容进行性能测试,然后再作决定。(如需指导,请观看我们的网络研讨会HTTP/2 有哪些新变化?。)

技巧 2:终止 HTTP/2 和 TLS

终止协议是指客户端使用所需的协议(如TLS或HTTP/2)连接到代理服务器。随后,代理服务器连接到应用服务器、数据库服务器等,但不一定使用相同的协议,如图所示。

使用单独的服务器执行终止处理,意味着需要转向多服务器架构。这些服务器可以是独立的物理服务器、虚拟服务器,也可以是部署在云环境(例如AWS)中的虚拟服务器实例。与单服务器架构,甚至应用服务器与数据库服务器的组合相比,这种架构更为复杂。但它能带来诸多优势,对于繁忙的网站而言,实际上几乎不可或缺。

在现有架构前端部署一台服务器或虚拟服务器后,即可实现多种功能。新服务器可接管其他服务器与客户端通信的任务,还可用于负载均衡、静态文件缓存等用途。这样便可根据需要轻松添加和替换应用服务器及其他服务器。

NGINX和NGINX Plus通常可用于实现上述所有目的,包括终止TLS和HTTP/2连接、负载均衡等。现有环境完全无需更改,只需在其前端部署NGINX服务器。

技巧3:考虑从SPDY入手

编者按:自本博文发布以来,主流浏览器已停止支持SPDY。因此,从SPDY入手已不再适合大规模部署。

SPDY是HTTP/2的前身协议,两者的整体性能大致相当。由于SPDY已推出数年,支持SPDY的Web浏览器数量多于支持SPDY的浏览器数量,而后者支持HTTP/2。不过,截至本文撰写时,这一差距正在缩小:约三分之二的Web浏览器支持HTTP/2,而约五分之四支持SPDY。

如果希望尽快实施新型Web传输协议,并在当前支持尽可能多的用户,可以先提供SPDY。随后,到2016年初开始移除SPDY支持时,可以切换到HTTP/2;至少使用NGINX时,这项变更可以快速完成。届时,将有更多用户使用支持HTTP/2的浏览器,因此在这一过渡期间,您可以为尽可能多的用户提供更合适的支持。

技巧4:确定HTTP/1.x优化的使用情况

在决定实施HTTP/2之前,需要先确定代码库中有多少内容针对HTTP/1.x进行了优化。需要注意以下4类优化:

  1. 域名分片:您可能已将文件放在不同的域名下,以提高向Web浏览器传输文件时的并行度;内容分发网络(CDN)会自动执行此操作。但在HTTP/2下,这种做法无助于提升性能,反而可能降低性能。可以使用支持HTTP/2的域名分片(请参阅“技巧7”),仅针对HTTP/1.x用户进行分片。
  2. 图像精灵:图像精灵是将多张图像合并为一个文件进行下载,再由单独的代码按需提取图像。使用HTTP/2时,图像精灵的优势有所减弱,但仍可能有用。
  3. 合并代码文件;与图像精灵类似,通常以单独文件形式维护和传输的代码块会合并为一个文件。随后,浏览器会根据需要在合并后的文件中查找并运行所需代码。
  4. 内联文件:将CSS代码、JavaScript代码甚至图像直接插入HTML文件。这样可以减少文件传输次数,但会导致首次下载的HTML文件体积增大。

最后三种优化方式都是将小文件合并为较大的文件,以减少新建连接和初始握手,而对于TLS而言,这些操作的开销尤其高。

第一种优化方法是域名分片,其做法恰恰相反,即通过引入更多域名来强制建立更多连接。这些看似相互矛盾的技术结合使用,可以较为有效地提升HTTP/1.x网站的性能。不过,设计、实施、管理和运行这些技术都需要投入时间、精力和资源。

在实施HTTP/2之前,请先确定这些优化措施应用于哪些位置,以及它们目前如何影响组织内的应用设计和工作流,以便迁移到HTTP/2后对其进行调整或撤销。

技巧 5:部署 HTTP/2 或 SPDY

实际上,部署HTTP/2或SPDY并不难。如果您使用NGINX,只需在NGINX配置中“启用”该协议即可。有关HTTP/2的具体操作,请参阅我们的白皮书《面向Web应用开发人员的HTTP/2》(PDF)。随后,浏览器和服务器将通过协商选择协议;如果浏览器也支持HTTP/2且使用了TLS,则会选择HTTP/2。

在服务器端实施HTTP/2后,使用支持HTTP/2的浏览器版本访问Web应用时,会话将通过HTTP/2运行。使用较旧浏览器版本时,会话将通过HTTP/1.x运行,如图所示。如果要为高流量网站实施HTTP/2或SPDY,建议建立相应流程,以衡量实施前后的性能,并在出现显著负面影响时回滚更改。

注意:HTTP/2使用单一连接,因此NGINX配置中的某些细节变得更加重要。请检查NGINX配置,尤其要注意调优和测试以下指令的设置:output_buffers、proxy_buffers和ssl_buffer_size。有关常规配置说明,请参阅《NGINX Plus管理指南》中的NGINX SSL/TLS终止。以下博客提供了更具体的建议:使用NGINX实现SSL卸载、加密和证书管理和如何使用HTTPS和NGINX改进SEO。白皮书NGINX SSL性能探讨了服务器密钥长度、服务器密钥协商和批量加密算法的选择如何影响性能。

注意:使用HTTP/2时,密码的使用可能需要格外注意。HTTP/2的RFC列出了一长串应避免使用的密码套件,您可能更倾向于自行配置密码列表。对于NGINX和NGINX Plus,建议调优ssl_ciphers指令并启用ssl_prefer_server_ciphers,同时使用常见浏览器版本测试配置。Qualys SSL Server Test可分析SSL Web服务器的配置,但截至2015年11月,该测试无法可靠检测HTTP/2握手。

技巧 6:调整 HTTP/1.x 优化设置

出人意料的是,在实施HTTP/2时,撤销或调整HTTP/1.x优化实际上是最需要发挥创造力的环节。需要考虑多个问题,具体如何处理也有很大的选择空间。

开始更改之前,请考虑这些更改是否会对旧版浏览器用户造成不利影响。基于这一点,可采用以下三类策略来撤销或调整HTTP/1.x优化:

  • 无需改动;如果尚未针对HTTP/1.x优化应用,或者只做了适度调整并愿意保留这些调整,则无需再做任何工作,即可让应用支持HTTP/2。
  • 混合方法:您可以减少文件和数据的合并,但不必完全取消。例如,可以保留将一组相关小图像合并为精灵图的做法,同时不再通过内联数据增大初始HTML文件。
  • 完全撤销针对HTTP/1.x的优化(但请参阅技巧 7中有关域名分片的说明),可以考虑彻底取消这些优化。

缓存的效果存在一定的不确定性。理论上,在存在大量小文件时,缓存的运行效果较好,但这也会产生大量文件I/O。将一些密切相关的文件合并起来,可能有助于改善工作流和应用性能。在实施HTTP/2时,请仔细权衡自身经验以及其他开发者分享的实践经验。

技巧 7:实施智能分片

域名分片可能是HTTP/1.x优化策略中最激进、也可能成效较为显著的一种。您可以采用一种域名分片方式,既能继续提升HTTP/1.x的性能,又基本不会影响HTTP/2,这反而对HTTP/2有利。(由于HTTP/2使用单一连接,域名分片通常无法为其带来性能提升。)

要实现适用于HTTP/2的域名分片,请满足以下两个条件:

  • 使分片资源的域名解析到同一IP地址。
  • 确保证书包含通配符,使其对分片所用的所有域名均有效;或者使用适当的多域名证书。

有关详细信息,请参阅RFC 7540《超文本传输协议第2版(HTTP/2)》。

如果满足这些条件,HTTP/1.x会进行域名分片,因为域名之间的差异足以触发浏览器创建更多连接组;而HTTP/2不会进行域名分片,因为这些不同的域名会被视为同一个域名,单个连接即可访问所有域名。

结论

HTTP/2和TLS有望提升网站性能,并让用户了解他们与网站的交互受到安全保护。无论您是率先实施HTTP/2,还是正在追赶竞争对手,都可以快速、顺利地添加HTTP/2支持。

参考这些技巧,以较少的持续投入提升HTTP/2性能,从而专注于创建快速、高效、安全且易于维护和运行的应用。

资源

  • 如需深入了解HTTP/2,请参阅NGINX白皮书(PDF)。
  • The Can I use网站显示了浏览器对多种前端Web技术的支持情况,包括SPDY和HTTP/2。
  • 截至2016年1月,超过6%的网站使用了HTTP/2。


分享

相关博客文章

NGINX Plus R26 正式发布
NGINX | 2022/02/15

NGINX Plus R26 正式发布

NGINX Plus R26通过缓存JSON Web密钥集加快JWT验证,并强化TLS握手,从而提升安全性。NGINX JavaScript的新功能包括增强对异步函数的支持,以及实现WebCrypto API。

使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击
NGINX | 2022/02/10

使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击

gRPC具备开发人员设计和部署现代应用所需的速度与灵活性,但其开放性也使其极易受到第7层DoS攻击。NGINX App Protect DoS可保护gRPC应用免受此类破坏性攻击。

Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划
NGINX | 2021/09/13

Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划

了解选择错误的Ingress控制器可能带来的风险,以及如何从关键方面着手,让您的选择更好地适应未来需求。

NGINX Plus R19 正式发布
NGINX | 2019/09/03

NGINX Plus R19 正式发布

NGINX Plus R19扩展了监控功能,不仅提供更多指标,还新增了指标分析方式;增加试运行模式,用于测试限速效果;增强键值存储,以支持IP地址范围;并使限速更加动态。

NGINX现已正式加入F5
NGINX | 2019/05/09

NGINX现已正式加入F5

NGINX现已正式成为F5的一部分。Gus Robertson现任F5 NGINX业务部门负责人。他阐述了两家公司在人才、文化和愿景方面融合的价值,以及双方将如何携手增强NGINX的开源产品和商业产品。

使用NGINX和NGINX Plus实现高性能缓存
NGINX | 2016/08/24

使用NGINX和NGINX Plus实现高性能缓存

我将介绍NGINX在内容缓存和性能方面的工作原理,并分享一些控制NGINX内容缓存方式的技巧。