Web服务器性能提升的建议
Web应用性能提升10倍的10个建议
一个网站需要多快?网页加载时间每增加 1 秒钟,就会有 4 % 的用户选择离开。顶尖的电子商务网站把第一次交互时间控制在 1-3 秒内,这样带来了很高的转换率。很明显 Web 应用性能的风险很高而且还在持续增长。
提升性能说起来容易,实现起来却很难。为了帮助大家,这篇文章提出了十个建议,可以让网站的性能提升 10 倍。本篇作为系列文章的第一篇,详细描述了如何借助一些验证过的优化技术和一点来自 NGINX 的帮助,就能提升应用的性能。该系列还概述了在安全性方面可能获得的改善。
一、利用反向代理服务器加速和保护应用
如果 Web 应用运行在一台独立的电脑上,性能问题的解决方案是显而易见的:换一台更快的电脑,里面加上更多的处理器、内存、快速磁盘阵列等等。然后在这台新电脑上运行 WordPress 服务、Node.js 应用、Java 应用等等,会比以前快很多。(如果应用需要访问服务器,方案还是很简单:换两台更快的电脑,用更快速的连接把它们连接起来。)
但电脑速度可能不是问题所在。通常 Web 应用运行缓慢,是由于电脑一直在不同的任务间切换:同成千上万的客户交互、访问磁盘上的文件、执行应用代码和其它的任务。应用服务器可能会因为下面这些问题而崩溃 —— 内存耗尽、把很多的数据从内存交换到磁盘上、以及很多请求都在等待一个类似磁盘 I/O 的单个任务。
你应该采用一种完全不同的方式,而不是升级硬件:增加一个反向代理服务器来分担这些任务。这台反向代理服务器设置在运行应用的电脑之前,用来处理网络流量。只有这台反向代理服务器直接连到网络上,它和应用服务器通过一个快速的内部网络进行通信。
利用这台反向代理服务器,应用服务器就不用等着和 Web 应用的用户进行交互,它可以专注在建立网页,并通过反向代理服务器把它们发送到网络上。因为应用服务器不必再等待客户的响应,所以能以最优的速度运行。
增加一台反向代理服务器也增加了 Web 服务器的弹性。如果一台服务器过载了,很容易增加另一台同类型的服务器。如果一台服务器宕机,也很容易把它换掉。
因为反向代理服务器带来的灵活性,它也成为了很多其它性能提升方法的先决条件,比如:
- 负载均衡(查看 建议二)—— 反向代理服务器上运行一个负载均衡器,把流量平均分配给一堆应用服务器。由于负载均衡器的引入,在增加应用服务器时可以完全不用修改应用程序
- 缓存静态文件(查看 建议三)—— 直接请求的文件,比如图片或者代码文件,可以存在反向代理服务器上,并直接发送给客户端,这样可以更快地提供服务,分担了应用服务器的负载,可以让应用执行得更快。
- 保护网站 —— 反向代理服务器可以设置较高的安全级别,通过监控进快速识别和响应攻击,这样就可以把应用服务器保护起来。
NGINX 软件是专门设计用做反向代理服务器的,具有上述这些附加功能。NGINX 利用事件驱动处理的方法,比其它传统的服务器更加高效。NGINX Plus 增加了更多反向代理的高级功能和支持,包含应用程序健康检查、特定请求路由和高级缓存等
二、增加一个负载均衡器
增加一个负载均衡器是一个相对简单的改动,而且会大幅度地改善网站的性能和安全性。你可以利用负载均衡器把业务分配给一些服务器,而不是建造一台更大更强的 Web 核心服务器。就算应用程序编写得很烂或者扩展性很差,负载均衡器都能提升用户体验而不需要任何其它的改动。
负载均衡器首先是一个反向代理服务器(查看建议一)—— 它接收网络流量,并把请求转交给另一个服务器。一个窍门就是让负载均衡器支持两台以上的应用服务器,利用一个选择算法在服务器间分配请求。最简单的方法就是轮询,每个新请求发送给列表中的下一台服务器。其它方法包括把请求发送给活动连接数量最少的服务器。NGINX Plus 可以在同一台服务器上维持一个给定的用户会话,这个功能被称为会话持久性。
负载均衡器可以极大地改善性能,因为它们避免让一台服务器过载,而其它服务器却处于空闲的状态。它们也很容易扩展 Web 服务器的能力,增加相对便宜的服务器并确保它们物尽其用。
负载均衡可以运用在很多协议上,包含HTTP、HTTPS、SPDY、HTTP/2、WebSocket、FastCGI、SCGI、uwsgi、memcache,还有一些应用程序,包含基于 TCP 的应用和 L4 协议。分析 Web 应用使用了什么技术和性能落后在什么地方。
同一台服务器或者用于负载均衡的服务器,还能处理其他任务,包含 SSL 终端、支持客户端使用的 HTTP/1/x 和 HTTP/2、以及缓存静态文件。
三、缓存静态和动态内容
缓存通过更快地向客户端提供内容来改善 Web 应用的性能。缓存包含一些策略:对内容预处理以便更快地发布、在更快的设备上保存内容、在更靠近客户端的地方保存内容,或者上述方法的组合。
- 静态内容的缓存。不经常变化的文件,比如图像文件(JPEG,PNG)和代码文件(CSS,JavaScript),可以存在一个边缘服务器上,以便在内存或磁盘上进行快速检索。
- 动态内容的缓存。很多 Web 应用为每个页面请求生成新的 HTML。通过简单地将已经生成 HTML的副本保存一小段时间,就可以大幅度减少需要生成页面的总数,发布这些已经生成的 HTML 副本已经足够满足需求了。
比如一个网页每秒有十次访问,把它缓存 1 秒钟,这个网页 90% 的请求都可以用缓存满足。如果你单独缓存静态内容,甚至最新生成的网页也会大量包含这些缓存的内容。
Web 应用生成缓存内容主要有三种技术:
- 让内容更靠近用户。内容副本靠近用户,可以减少传输时间。
- 把内容存在更快的电脑上。内容可以保存在更快的电脑上以便加快检索。
- 把内容移出过载的电脑。有时候电脑运行一个特定任务比基准性能要慢,这是因为它同时还在忙其他任务。把缓存设置在另一台电脑上,都能提升有缓存资源和没有缓存资源的性能,因为这台主机不再过载了。
设置 Web 应用的缓存从 Web 应用服务器开始,是从内到外来实现的。首先,缓存动态内容,减轻了应用服务器的负担。接下来,缓存静态内容(包括原本是动态内容的临时副本),进一步分担应用服务器的负担。然后把缓存从应用服务器移到更快的、距离用户更近的电脑上,这样卸下了应用服务器的负担,减少了检索和传输的时间。
提高缓存可以大大加快应用程序。大多数网页中,一半以上的内容都是静态数据(比如大的图像文件)。在没有缓存的情况下,检索和传输数据可能要花费好几秒钟,但如果数据缓存在本地,只需要几分之一秒就可以。
举一个例子说明实际上如何使用缓存,NGINX 和 NGINX Plus 用两条指令来创建缓存:proxy_cache_path 和 proxy_cache。你指定了缓存的位置和大小、文件保存在缓存的最长时间和其它参数。使用的第三条指令(也相当常用),proxy_cache_use_stale,甚至可以在服务器忙碌或挂掉而不能提供最新内容的情况下,由缓存直接提供过期的内容,给客户端提供一些东西总比什么都没有强。从用户的角度来看,这会大大改善网站和应用的正常运行时间。
NGINX Plus 有一些高级的缓存功能,包括支持缓存清除,和将缓存状态可视化并显示在 dashboard 上,用于监控实时活动。
关于 NGINX 缓存的更多信息,可以参考相关文档和 《NGINX Plus 管理指南》的「NGINX 内容缓存」章节。
注意:缓存跨越了组织间的界限,让从事应用开发的人、进行资本投资决策的人和维护网站的人都参与其中。成熟的缓存策略就像这里提到的,很好得体现了DevOps 方式的价值,也就是应用程序员、架构师和运维人员等各方力量都团结起来,努力达成对网站的功能、响应时间、安全性和业务结果(比如完成的交易量或销售额)的要求。
四、压缩数据
压缩是一个有巨大潜能的性能加速器。已经有很多精心设计和高效的压缩标准,有针对图像的(JPEG 和 PNG)、视频的(MPEG-4)、音乐的(MP3)等等。这些标准都可以大幅减少文件的大小。
文本数据 —— 包含 HTML(包含了纯文本和 HTML 标签)、CSS 和类似 JavaScript 的代码,这些数据通常不经过压缩就进行传输了。压缩这些数据会大大改善对 Web 应用性能的体验,特别是那些连接缓慢或受限的移动客户端。
这是因为用户在和网页交互时,文本数据通常已经足够了,而多媒体数据就需要更多的支持。智能内容压缩可以减少 HTML、Javascript、CSS 和其它文本内容对带宽的要求,通常是 30% 或者更多,从而减少加载时间。
压缩文本数据的方法有所不同。比如,本文的 HTTP/2 章节提到的一种新颖的文本压缩方案,专门用来压缩头部数据。另一个例子是可以在 NGINX 中打开 GZIP。对文本数据进行预先压缩后,可以通过 gzip_static 指令直接提供 .gz 的压缩文件(给客户端)。
五、优化SSL/TLS
加密套接字层(SSL)协议及其后继者 —— 传输层安全(TLS)协议,被越来越多得的网站所采用。SSL/TLS 加密了服务器发送给用户的数据,提升了网站的安全性。影响这一趋势的部分原因是,Google 现在提升了启用 HTTPS 网站的搜索排名。
尽管 SSL/TLS 越来越普遍,它们却是影响许多网站性能的症结所在。SSL/TLS 降低网站性能有两个原因:
-
每当打开一个新的连接,最初的握手都需要建立加密密钥。浏览器使用 HTTP/1.x 和服务器建立多条连接,随着服务器的增多,连接会成倍增加。
-
服务器上加密数据,客户端解密数据,这些都是持续的开销。
为了鼓励使用 SSL/TLS,HTTP/2 和 SPDY (在下一章节详细介绍)的作者在设计协议时,让每个浏览器会话只使用一个连接。这样大大减少了 SSL 开销的一个重要来源。但是,在提升基于 SSL/TLS 的应用性能方面,还是有很多可以做的事情。
优化 SSL/TLS 的机制因 Web 服务器而有所差别。比如,NGINX 使用 OpenSSL,运行在标准硬件上,提供类似专用硬件解决方案的性能。NGINX SSL 性能解决方案有详细的文档、减少了 SSL/TLS 加解密对 CPU 和 时间的消耗。
此外,这篇文章中还详细介绍了提升 SSL/TLS 性能的各种方式。简单总结一下,这些技术包括:
会话缓存。使用 ssl_session_cache 指令,缓存 SSL/TLS 加密每个新连接所使用的参数。
会话标签或 ID。这些特定 SSL/TLS 会话信息都存在一个标签或 ID 中,所以可以顺畅地重用一个连接,而不需要再次握手。
OCSP 封装。缓存 SSL/TLS 证书信息,来缩短握手时间。(译者注:OCSP,Online Certificate Status Protocol,在线证书状态检查协议(RFC6960),用来向 CA 站点查询证书状态,比如是否撤销。通常情况下,浏览器使用 OCSP 协议发起查询请求,CA 返回证书状态内容,然后浏览器接受证书是否可信的状态。这个过程非常消耗时间,因为 CA 站点有可能在国外,网络不稳定,RTT 也比较大。那有没有办法不直接向 CA 站点请求 OCSP 内容呢?OCSP 封装(stapling) 就能实现这个功能。简单原理就是浏览器发起 client hello 时会携带一个 certificate status request 的扩展,服务器看到这个扩展后将 OCSP 内容直接返回给浏览器,完成证书状态检查。由于浏览器不需要直接向 CA 站点查询证书状态,这个功能对访问速度的提升非常明显。 )
NGINX 和 NGINX Plus 可以用在 SSL 或 TLS 终端上 —— 当和其它服务器进行明文通信时,对客户端流量进行加解密。按照这些步骤设置 NGINX 或 NGINX Plus,就能用在 SSL 或 TLS 终端上。当用在接受 TCP 连接的服务器上,NGINX Plus 还有特别的设定步骤。
十、监控实时活动来解决问题和瓶颈
监控可以抓到不同类型的问题。它们包含:
- 服务器宕机。
- 服务器不稳定,容易掉线。
- 服务器大概率出现缓冲失效。
- 服务器发送的内容不正确。
你可以使用 New Relic 或 Dynatrace 这种全球性的应用性能监控工具,来监控遥远地方加载页面的时间,也可以利用 NGINX 监控应用程序的发布。当你考虑是否需要给基础设施扩容来维持流量时,应用性能数据可以告诉你这些优化是否真能给用户带来很大的改善。