提高Web应用程序的性能从未像今天这样紧迫。在线经济活动的比重越来越大,即使在发展中国家和地区,也有超过5%的经济活动在线进行(相关数据参见本文后面的资源)。在这个高度连接、永远在线的现代世界中,用户的期望与过去大相径庭。如果您的网站没有立即响应,您的应用程序就无法立即运行,用户就会转向您的竞争对手。亚马逊大约10年前的一项研究表明,页面加载时间减少1/10秒与收入增加1%有关。最近的另一项调查还显示,超过一半的受访网站所有者表示,由于应用程序性能不佳而导致收入损失或用户流失。一个网站有多快?每每秒加载一个页面,大约4%的用户就会离开。排名靠前的电子商务网站的首次交互时间为1到3秒,这是转化率最高的范围。很明显,Web应用程序性能的重要性与日俱增。提升性能不难,难的是如何看到结果。本文给出10条可以提高网站性能10倍左右的建议,供大家参考。这是第一次如此全面地涵盖各种性能优化技术,但这些建议可能需要NGINX的一点支持。除了性能之外,这些建议还涉及提高安全性。1建议一:使用反向代理服务器,让应用更快更安全。如果你的web应用只运行在一台机器上,提高它的性能很简单:换一个更快的,多配置几个处理器,多加几个内存条,磁盘阵列也应该是高速的。切换后,本机上运行的WordPress服务器、Node.js或Java应用程序都会提速。(如果应用程序还访问另一个数据库服务器,这很容易:找到两台更快的机器并将它们连接到更快的网络。)问题是,机器速度不是问题。很多时候,Web应用程序很慢,因为它们必须在各种任务之间切换。他们一会儿要处理成千上万个连接的用户请求,一会儿要读写文件到磁盘,一会儿要运行应用程序代码,一会儿还要去上班。别的东西。因此,应用服务器可能会遇到各种情况,内存不足,交换文件,或使许多请求等待硬盘I/O等任务。除了升级硬件之外,其实你还可以选择另一种完全不同的方法:添加一个反向代理服务器来分担上面的一些任务。反向代理服务器位于运行应用程序的机器前面,负责处理来自外部网络的请求。反向代理服务器直接连接到互联网,它使用快速的内部网络与应用服务器通信。反向代理服务器可以让应用服务器专注于构建页面,然后交给反向代理发送到外网,而不管用户与应用的交互。由于不必等待来自客户端的响应,应用服务器可以以接近最佳的速度运行。添加反向代理服务器还可以增加Web服务器的灵活性。例如,如果执行某项任务的服务器超载,则可以随时添加另一台相同类型的服务器;如果这台服务器坏了,很容易更换它。鉴于这种灵活性,反向代理服务器往往是其他性能优化方法的前提,例如:负载均衡(参见“建议2”),在反向代理服务器上运行负载均衡服务,将流量平均分配给几个应用程序服务器。通过负载平衡,添加应用服务器根本不需要修改应用程序。缓存静态文件(参见“建议3”),可以直接请求的文件,比如图片或者代码,可以存储在反向代理服务器中,以便直接发送给客户端。这样不仅可以更快地响应请求,还可以减轻应用服务器的负载,加快速度。为了保证站点的安全,您可以配置反向代理服务器来提高其安全级别,并对其进行监控,以快速识别和应对攻击,从而保护应用服务器的安全。NGINX专为配合反向代理服务器而设计,自然而然地支持了上述优化。由于使用了事件驱动的处理机制,NGINX比传统服务器更高效。NGINXPlus添加了更高端的反向代理功能,例如应用程序健康检查、唯一请求路由、高级缓存和售后支持。传统服务器与NGINXWorker对比建议二:添加负载均衡服务器添加负载均衡服务器相对简单,但可以显着提高站点性能和安全性。通过将流量分配到多个服务器,无需升级Web服务器。即使应用程序本身编写得不好或难以扩展,负载平衡也可以在不进行其他更改的情况下改善用户体验。负载均衡服务器首先是一个反向代理服务器(参见“建议1”),负责将来自互联网的请求转发给其他服务器。这里的关键是负载均衡服务器可以支持两台以上的应用服务器,通过选择算法在不同的服务器之间分配请求。最简单的负载均衡算法是循环调度,它将新请求按顺序转发到下一个可用的服务器。其他算法包括将请求路由到活动连接最少的服务器。NGINXPlus支持将用户会话保持在同一台服务器上的功能,称为会话持久化。负载平衡服务器可以通过防止一台服务器过载而其他服务器空闲来极大地提高性能。同时,有了它,还可以让Web服务器的扩展变得更加容易,因为你可以选择更便宜的服务器,同时又能保证物尽其用。可以通过负载均衡进行调度的协议有HTTP、HTTPS、SPDY、HTTP/2、WebSocket、FastCGI、SCGI、uwsgi、memcached以及其他一些应用形式,包括基于TCP的应用和其他第四层协议。为此,首先要分析Web应用程序,看看性能不足的地方在哪里,然后再决定使用哪一个。用于负载平衡的同一台服务器或一台服务器还可以承担其他任务,例如SSL终止、根据客户端支持HTTP/1/x或HTTP/2以及缓存静态文件。NGINX通常用于负载均衡。有关更多信息,请参阅我们之前的介绍性文章、有关配置的文章、电子书和相关在线视频,当然还有文档。我们的商业版NGINXPlus支持更多的负载均衡特性,比如根据服务器响应时间路由负载,支持MicrosoftNTLM协议负载均衡。建议3:缓存静态和动态内容缓存可以提高Web应用程序性能,因为内容可以更快地交付给客户端。缓存策略包括预处理内容、将内容存储在更快的设备上、使内容靠近客户端以及同时应用这些策略。有两种类型的缓存。静态内容缓存、不经常更改的文件,例如图像(JPEG、PNG)和代码(CSS、JavaScript),可以保存在边缘服务器中,以便从内容或磁盘中快速获取。动态内容缓存,许多Web应用程序会为每个页面请求生成新的HTML,并将每个生成的HTML缓存一小段时间,这可能会显着减少需要生成的页面总数,同时确保交付的内容是够新鲜。假设一个页面每秒被浏览10次,你缓存它1秒,那么这个页面90%的请求都会来自于缓存。如果您单独缓存静态内容,即使是新生成的页面也很可能来自缓存内容。缓存Web应用程序生成的内容主要有三种技术。将内容放在靠近用户的位置。离用户更近,传输时间更短。将内容放在更快的机器上。机器快,检索速度快。从过度使用的机器上删除内容。有时机器比专注于特定任务时要慢得多,因为它们被太多任务分心了。这时,将内容带到其他机器上不仅对缓存内容有好处,对非缓存内容也有好处,因为托管它们的主机的负担减轻了。Web应用程序缓存可以在Web应用程序服务器内部或外部实现。首先,考虑缓存动态内容以减少应用程序服务器上的负载。其次,缓存用于静态内容(包括那些动态生成的内容的临时副本),进一步卸载应用程序服务器。然后,考虑将缓存移动到其他更快或更接近用户的机器上,减少应用服务器的负载并缩短传输时间。良好地使用缓存可以显着加快应用程序的响应时间。对于很多网页来说,大图片等静态数据往往会占据一半以上的内容。如果没有缓存,查询和传输这种类型的数据可能需要几秒钟,但如果有缓存,可能只需要几分之一秒。可以举个例子来说明如何使用缓存。NGINX和NGINXPlus通过两条指令设置缓存:proxy_cache_path和proxy_cache指定缓存的位置和大小,最长缓存时间等参数。使用第三个(也是流行的)指令proxy_cache_use_stale,您甚至可以告诉缓存在本应提供新内容的服务器太忙或宕机时提供原始旧文件。对于客户来说,得到内容总比不能变强好。从用户的角度来看,这也可以为您的网站或应用程序树立一个非常稳定的形象。NGINXPlus支持高级缓存功能,包括缓存清除和通过仪表板可视化显示缓存状态以进行实时监控。要了解有关NGINX缓存的更多信息,请参阅NGINXPlus管理指南中的参考文档和NGINX内容缓存。注:缓存涉及开发、决策和运维。一个完整的缓存策略,比如本文提到的那些,能够体现出从DevOps的角度考虑的价值。换句话说,开发人员、架构师和运维人员一起工作,以确保网站的功能、响应时间、安全和业务目标。建议四:压缩数据压缩也可以大大提高性能。图片、视频、音乐等文件都有非常成熟和高效的压缩标准(JPEG、PNG、MPEG-4、MP3),任何一种标准都可以将文件大小减少一个数量级甚至更多。文本文件,包括HTML(纯文本和HTML标签)、CSS和JavaScript代码,通常在没有压缩的情况下传输。压缩此数据有时可以显着提高Web应用程序的感知性能,尤其是在移动用户的网络缓慢且不稳定的情况下。因为文本数据可以对页面交互起到必要的支撑作用,而多媒体数据更多的是锦上添花。智能内容压缩可以将HTML、JavaScript、CSS等文本内容压缩30%以上,从而相应减少加载时间。如果您使用SSL,压缩会减少必须进行SSL编码的数据量,从而补偿压缩此数据所花费的CPU时间。有很多方法可以压缩数据。例如,Recommendation6中关于HTTP/2的部分描述了一种新颖的压缩思想,它特别适用于头部数据压缩。另一个关于文本压缩的例子是你可以在NGINX中启用GZIP压缩。预压缩文本数据后,可以使用gzip_static指令直接发送.gz文件。建议5:优化SSL/TLS越来越多的网站正在使用安全套接字层(SSL)和后来的传输层安全(TLS)协议。SSL/TLS通过加密从源服务器发送到用户的数据来提高网站安全性。Google将提高使用SSL/TLS的网站的搜索引擎排名,这将有效推动这一进程。尽管采用率越来越高,但SSL/TLS造成的性能损失困扰着许多网站。SSL/TLS会降低网站速度有两个原因。1.每次打开新连接时都必须为初始握手创建加密密钥,而浏览器使用HTTP/1.x与每个2.服务器建立多个连接的方式进一步加剧了这个问题。服务器端加密数据和客户端解密数据的操作也是有开销的。为了鼓励人们使用SSL/TLS,HTTP/2和SPDY的作者(参见建议6)设计了这两种协议,以便浏览器每次会话只建立一个连接。这消除了由SSL引起的性能下降的两个主要原因之一。然而,在优化SSL/TLS性能方面,还有很多工作要做。优化SSL/TLS的方法因Web服务器而异。以NGINX为例。NGINX使用OpenSSL并在普通机器上运行,可以提供接近于自定义机器的性能。NGINXSSL性能详细介绍了如何最小化SSL/TLS加密和解密的开销。另外,这里有一篇文章介绍了很多提高SSL/TLS性能的方法。简单概括一下,涉及的技术主要有以下几点。会话缓存。使用ssl_session_cache命令启用缓存并缓存每个SSL/STL连接中使用的参数。会话票证或ID。将有关特定SSL/TLS会话的信息保存为会话票证或ID,以便可以重复使用连接而无需重新握手。OCSP信封。通过缓存SSL/TLS证书信息减少握手时间。NGINX和NGINXPlus都可以终止SSL/TLS,即处理客户端信息的加密和解密,同时保持与其他服务器的明文通信。您可以采取几个步骤来设置处理NGINX或NGINXPlus中的SSL/TLS终止。要在接受TCP连接的服务器上使用NGINXPlus,您可以参考此处的设置步骤。建议6:实施HTTP/2或SPDY对于已经使用SSL/TLS的站点,如果再次使用HTTP/2或SPDY,可能会提高性能,因为一个连接只需要一次握手。尚未使用SSL/TLS、HTTP/2和SPDY的站点切换到SSL/TLS(通常以性能成本为代价)可能在响应能力方面倒退了一步。Google于2012年启动了SPDY项目,致力于在HTTP/1.x之上实现更快的速度。HTTP/2是IETF最近批准的基于SPDY的标准。SPDY得到广泛支持,但很快就会被HTTP/2取代。SPDY和HTTP/2的关键是只使用一个连接,而不是多个连接。这个连接是多路复用的,因此可以同时承载多个请求和响应。只维护一个连接可以节省多个连接的设置和管理开销。而一个连接对于SSL来说尤为重要,因为SSL/TLS建立安全连接所需的握手时间可以最小化。SPDY协议需要使用SSL/TLS,HTTP/2并没有正式要求,但目前所有支持HTTP/2的浏览器只有在启用SSL/TLS的情况下才会使用它。换句话说,如果网站使用SSL并且服务器接受HTTP/2流量,则支持HTTP/2的浏览器将仅使用HTTP/2。否则,浏览器通过HTTP/1.x进行通信。实现SPDY或HTTP/2后,之前的域名分片、资源合并、图片精灵等HTTP性能优化措施都不再需要了。因此也可以简化代码和部署。关于HTTP/2会带来的变化,可以参考我们的白皮书。NGINX长期以来一直支持SPDY,如今大多数使用SPDY的站点都在运行NGINX。NGINX也率先支持了HTTP/2。2015年9月,NGINX开源,NGINXPlus开始支持HTTP/2。随着时间的推移,NGINX期望大多数站点启用SSL并迁移到HTTP/2。这不仅使网站更安全,而且随着新的优化技术的出现,还可以通过更简单的代码实现更好的性能。建议7:升级软件提高应用程序性能的一个简单方法是根据可靠性和性能选择软件。此外,高质量组件的开发者更有可能持续改进性能和修复问题,因此使用最新的稳定版本是值得的。新发布的版本将得到开发人员和用户的更多关注,还将利用新的编译器优化技术,包括针对新硬件进行调优。与旧版本相比,新发布的稳定版性能明显提升。坚持升级还可以让您了解最新的调整、错误修复和安全警报。未能升级软件也会妨碍利用新功能。例如,HTTP/2目前需要OpenSSL1.0.1。从2016年下半年开始,HTTP/2将需要2015年1月发布的OpenSSL1.0.2。NGINX用户可以从最新版本的NGINX开源软件或NGINXPlus入手,支持套接字共享、线程池(见下文),两者都在继续优化性能。因此,请检查您的软件并尝试将它们更新到最新版本。建议8:调优LinuxLinux是当今大多数Web服务器的底层操作系统。作为所有基础架构的基础,Linux对于提高性能至关重要。默认情况下,很多Linux系统都比较保守,只以桌面办公为需求,占用资源少为调优目标。对于web应用来说,为了达到最好的性能,肯定是需要重新调优的。Linux优化因Web服务器而异。以NGINX为例,可以从以下几个方面考虑。库存队列。如果发现有些连接无法处理,可以增加net.core.somaxconn,这是等待NGINX处理的最大连接数。如果此连接限制太低,您应该会看到一条错误消息,您可以逐渐增加此值,直到错误消息不再出现。文件描述符。NGINX每个连接最多使用两个文件描述符。如果系统服务于许多连接,可能需要增加sys.fs.file_max系统级描述符限制和nofile用户文件描述符限制以支持增加的负载。临时端口。当用作代理时,NGINX为每个上游服务器创建临时端口。可以设置net.ipv4.ip_local_port_range来增加端口值的范围来增加可用端口的数量。此外,还可以降低net.ipv4.tcp_fin_timeout的值,控制非活跃端口被释放和重用的等待时间,以加快周转速度。对于NGINX,请参阅NGINX性能调优指南,了解如何优化您的Linux系统以支持更大的吞吐量而不费吹灰之力。建议九:调整Web服务器无论您使用什么Web服务器,您都需要为您的应用程序调整它。以下建议适用于任何Web服务器,但仅提供NGINX的设置说明。访问日志。每次请求的log不要马上写到磁盘,可以在内存中做一个缓存,然后批量设置。对于NGINX,在access_log命令中加入buffer=_size_参数,待内存缓冲区满后,再将日志写入磁盘。如果加上**flush=_time_**参数,那么buffer的内容也会按照指定的时间写入磁盘。缓冲。缓冲用于将部分响应保存在内存中,直到缓冲区被填满,从而能够更有效地响应客户端。无法写入内存的响应将写入磁盘,从而降低性能。启用NGINX缓冲后,可以使用proxy_buffer_size和proxy_buffers指令对其进行管理。客户端活动连接。活动连接可以减少时间消耗,尤其是在使用SSL/TLS时。对于NGINX,可以增加客户端keepalive_requests的值,默认值为100;也可以增加keepalive_timeout的值,让活动连接持续的时间更长,这样后续的请求就可以更快的得到响应。上游活动连接。上游连接,即到应用程序服务器、数据库服务器的连接,也可以从活动连接设置中受益。对于上游连接,可以增加活动连接,这是每个工作进程可用的空闲活动连接数。这提高了连接重用并减少了重新打开连接。有关活动连接的更多信息,请参阅此博客文章。限制。限制客户端使用的资源可以提高性能和安全性。对于NGINX,limit_conn和limit_conn_zone指令限制到给定源的连接数,而limit_rate限制带宽。这些设置可以防止合法用户“吞噬”资源,还有助于防止攻击。limit_req和limit_req_zone指令限制客户端请求。对于与上游服务器的连接,可以在上游配置区的server指令中使用max_conns参数,限制与上游服务器的连接,防止过载。关联的队列指令创建一个队列,在达到max_conns限制后,该队列在指定的时间内保存指定数量的请求。工作过程。工作进程负责处理请求。NGINX使用基于事件的模型和依赖于操作系统的机制在工作进程之间有效地分发请求。建议将worker_processes的值设置为每个CPU一个工作进程。如果需要,大多数系统都支持增加worker_connections的值(默认为512)。您可以尝试找到最适合您的系统的值。套接字碎片。通常,一个套接字侦听器将新连接分发给所有工作进程。套接字碎片为每个工作进程创建一个套接字侦听器,内核在可用时为套接字侦听器分配一个连接。这减少了锁争用并提高了多核系统的性能。要启用套接字碎片,请在listen指令中包含reuseport参数。线程池。阻塞任何计算机进程的耗时操作。对于Web服务器软件,磁盘访问会阻碍许多更快的操作,例如内存计算和复制。使用线程池,将慢速操作分配给一组单独的任务,而主处理循环继续运行较快的操作。磁盘操作完成后,将结果返回主处理循环。在NGINX中,read()系统调用和sendfile()被卸载到线程池中。提示在修改任何操作系统和外围设备设置时,一次更改一个并测试性能。如果更改导致问题,或者没有提高性能,请将其更改回来。建议10:监控实时动态以发现问题和瓶颈保持应用程序高性能的关键是实时监控应用程序性能。必须实时监控相应网络基础设施中特定设备和应用程序的动态。监控站点活动主要是被动的,它只会告诉您发生了什么,发现和解决问题取决于您。监控可以捕捉到以下问题:1、服务器宕机2、服务器不稳定,丢失连接处理3、服务器大规模缓存失效4、服务器发送的内容不正确。NewRelic或Dynatrace等全局性能监控工具可以帮助我们监控远程加载页面的时间,而NGINX可以帮助您监控应用交付端。应用的性能数据可以告诉你什么时候优化方式真正给用户带来了不一样的体验,什么时候需要扩展以满足不断增长的流量。为了帮助用户尽快发现问题,NGINXPlus新增了应用健康检查功能,对于频繁重复出现的问题会进行上报。NGINXPlus还具有会话耗尽功能,它会在现有任务完成之前阻止新连接,并具有慢速启动功能,以便恢复的服务器可以在负载平衡的集群中达到最高速度。如果使用得当,健康检查将帮助您在问题严重影响用户体验之前找到问题,而会话耗尽和启动缓慢允许您在不影响感知性能和正常运行时间的情况下更换服务器。此图显示了内置于NGINXPlus中的实时活动监控仪表板,涵盖服务器、TCP连接和缓存。结论:10倍的性能提升性能提升因Web应用程序的不同而有很大差异。实际的改进取决于预算、时间以及现有实施与理想性能之间的差距。那么如何让应用程序的性能提高10倍呢?为了帮助大家了解每条优化建议的潜力,下面会针对之前的建议给出一些实施指南,希望大家取其所好。反向代理服务器和负载平衡。如果没有负载平衡或池负载平衡,可能会导致性能极差。添加反向代理服务器(例如NGINX)可以减少Web应用程序在内存和磁盘之间的往返次数。负载均衡可以将任务从过载的服务器转移到空闲的服务器上,也便于扩展。这些更改可以大大提高性能。与原来部署方式最差的时候相比,性能提升10倍是非常容易的。哪怕是不到10倍,总的来说也是质的飞跃。缓存动态和静态内容。如果你的web服务器同时充当应用服务器,那么通过缓存动态内容,你可以在高峰期实现10倍的性能提升。缓存静态内容也可以将性能提高数倍。压缩数据。使用JPEG、PNG、MPEG-4和MP3等压缩格式可以显着提高性能。如果使用这些方法,那么压缩的文本数据(代码和HTML)可以将初始页面加载时间缩短两倍。优化SSL/TLS。安全握手对性能有很大影响,因此对其进行优化可以使初始响应速度提高一倍,尤其是对于文本密集型站点。在SSL/TLS下优化媒体文件带来的性能提升很小。实施HTTP/2和SPDY。在SSL/TLS的情况下,这两个协议有可能提高网站的整体性能。调整Linux和Web服务器。使用优化的缓冲策略,使用活动连接,将耗时的任务卸载到独立的线程池中,可以显着提高性能。例如,线程池可以将磁盘密集型任务的性能提高至少一个数量级。
