NGINX是众所周知的高性能负载均衡器、缓存和web服务器,为世界上40%以上最繁忙的网站供电。对于大多数用例,默认的NGINX和Linux设置工作得很好,但是要获得最佳性能有时需要进行一些调整。这篇博客文章讨论了在优化系统时要考虑的一些NGINX和Linux设置。
几乎可以对任何设置进行优化,但本文将集中讨论少数几个对大多数用户有利的设置。只有当您对NGINX和Linux有了深入的了解,或者按照我们的支持或专业服务团队的指导,我们才建议您更改某些设置,这里不介绍这些设置。专业服务团队与世界上一些最繁忙的网站合作,优化NGINX以获得最高级别的性能,并可与您一起充分利用NGINX或NGINX Plus部署。
介绍
假设对NGINX架构和配置概念有基本的了解。本文并不试图复制NGINX文档,而是提供了各种选项的概述以及到相关文档的链接。
优化时要遵循的一个好规则是一次更改一个设置,如果更改不能提高性能,则将其设置回默认值。
我们首先讨论Linux的调优,因为某些操作系统设置的值决定了如何调优NGINX配置。
调整Linux配置
现代Linux内核(2.6+)中的设置适用于大多数目的,但更改其中的一些设置可能是有益的。检查内核日志中指示设置过低的错误消息,并根据建议进行调整。在这里,我们只讨论那些在正常工作负载下最有可能从优化中受益的设置。有关调整这些设置的详细信息,请参阅Linux文档。
积压队列(The Backlog Queue)
以下设置与连接及其排队方式相关。如果传入连接的速率很高,并且性能水平参差不齐(例如,某些连接似乎处于暂停状态),则更改这些设置可能会有所帮助。
- net.core.somaxconn–可排队等待NGINX接受的最大连接数。默认值通常很低,这通常是可以接受的,因为NGINX可以很快接受连接,但如果您的网站遇到大量流量,则可以增加它。如果内核日志中的错误消息指示该值太小,请增大该值,直到错误停止。
- 注意:如果将其设置为大于512的值,请将backlog参数更改为NGINX listen指令以进行匹配。
- net.core.netdev_max_backlog–在将数据包交给CPU之前,网卡缓冲数据包的速率。增加该值可以提高具有高带宽的计算机上的性能。检查内核日志中是否存在与此设置相关的错误,并参考网卡文档中有关更改此设置的建议。
描述器
文件描述符是用于表示连接和打开的文件等的操作系统资源。NGINX每个连接最多可以使用两个文件描述符。例如,如果NGINX正在代理,它通常使用一个文件描述符作为客户端连接,另一个用于连接到代理服务器,尽管如果使用HTTP keepalives,这个比率要低得多。对于提供大量连接的系统,可能需要调整以下设置:
- sys.fs.file-max–文件描述符的系统范围限制
- nofile–在/etc/security/limits.conf文件中设置的用户文件描述符限制
短暂的端口(Ephemeral Ports)
当NGINX充当代理时,到上游服务器的每个连接都使用一个临时或短暂的端口。您可能需要更改此设置:
- net.ipv4.ip_local_port_range–端口值范围的开始和结束。如果发现端口不足,请增大范围。常见的设置是端口1024到65000。
调整NGINX配置
下面是一些可以影响性能的NGINX指令。如上所述,我们只讨论对您自己调整安全的指令。我们建议您不要在没有NGINX团队指导的情况下更改其他指令的设置。
工作进程(Worker Processes)
NGINX可以运行多个工作进程,每个进程都能够处理大量的同时连接。您可以使用以下指令控制工作进程的数量以及它们如何处理连接:
- worker_processes–NGINX工作进程的数量(默认值为1)。在大多数情况下,每个CPU核心运行一个工作进程工作良好,我们建议将此指令设置为auto以实现这一点。有时您可能希望增加这个数字,例如工作进程必须执行大量磁盘I/O。
- worker_connections–每个工作进程可以同时处理的最大连接数。默认值是512,但大多数系统都有足够的资源来支持更大的数目。适当的设置取决于服务器的大小和流量的性质,并且可以通过测试发现。
保持连接(Keepalive Connections)
Keepalive连接可以减少打开和关闭连接所需的CPU和网络开销,从而对性能产生重大影响。NGINX终止所有客户端连接,并创建到上游服务器的独立连接。NGINX支持客户端和上游服务器的keepalives。以下指令与客户端keepalives相关:
- keepalive_requests –客户端可以通过单个keepalive连接发出的请求数。默认值为100,但更高的值对于使用负载生成工具进行测试尤其有用,该工具通常从单个客户端发送大量请求。
- keepalive_timeout -空闲keepalive连接保持打开的时间。
以下指令与上游保持连接有关:
- keepalive–到上游服务器的空闲keepalive连接数,每个工作进程都保持打开状态。没有默认值。
要启用到上游服务器的keepalive连接,还必须在配置中包含以下指令:
proxy_http_version 1.1; proxy_set_header Connection "";
访问日志记录
记录每个请求会占用CPU和I/O周期,减少影响的一种方法是启用访问日志缓冲。使用缓冲,NGINX不会对每个日志条目执行单独的写操作,而是缓冲一系列条目,并在单个操作中将它们一起写入文件。
要启用访问日志缓冲,请将buffer=size参数包含到access_log指令中;NGINX在缓冲区达到size值时将缓冲区内容写入日志。要让NGINX在指定时间后写入缓冲区,请包含flush=time参数。当设置了这两个参数时,NGINX会在下一个日志条目无法放入缓冲区或缓冲区中的条目分别早于指定的时间时将条目写入日志文件。当工作进程重新打开其日志文件或关闭时,也会写入日志项。要完全禁用访问日志记录,请将off参数包含到access_log指令中。
发送文件(Sendfile)
操作系统的sendfile()系统调用将数据从一个文件描述符复制到另一个文件描述符,通常实现零拷贝,这可以加快TCP数据传输。要使NGINX能够使用它,请在http上下文或服务器或位置上下文中包含sendfile指令。然后,NGINX可以将缓存或磁盘上的内容写入套接字,而无需将任何上下文切换到用户空间,从而使写入速度极快,占用更少的CPU周期。但是,请注意,由于使用sendfile()复制的数据绕过了用户空间,因此它不受常规NGINX处理链和更改内容的过滤器(如gzip)的约束。当配置上下文同时包含sendfile指令和激活内容更改筛选器的指令时,NGINX会自动为该上下文禁用sendfile。
限制
您可以设置各种限制,帮助防止客户端消耗太多资源,这可能会对系统性能以及安全性和用户体验造成不利影响。以下是一些相关指令:
- limit_conn and limit_conn_zone–限制NGINX接受的客户端连接数,例如从单个IP地址。设置它们有助于防止单个客户端打开过多的连接并消耗超过其资源份额的资源。
- limit_rate–限制每个连接将响应传输到客户端的速率(以便打开多个连接的客户端可以为每个连接消耗此数量的带宽)。设置限制可以防止系统被某些客户端过载,从而确保所有客户端的服务质量更加均匀。
- limit_req and limit_req_zone–限制NGINX处理请求的速率,这与设置limit_rate有相同的好处。它们还可以提高安全性,特别是登录页面的安全性,方法是将请求速率限制为对人类用户合理的值,但对于试图用请求压倒应用程序的程序(如DDoS攻击中的机器人程序)来说太慢。
- 上游配置块中服务器指令的max_conns参数-设置上游组中服务器同时接受的最大连接数。设置一个限制可以帮助防止上游服务器过载。将该值设置为0(零,默认值)意味着没有限制。
- queue(NGINX Plus)–创建一个队列,当上游组中的所有可用服务器都达到最大连接数限制时,将在其中放置请求。此指令设置队列中请求的最大数量,还可以选择设置在返回错误之前它们等待的最长时间(默认为60秒)。如果省略此指令,则请求不会排队。
缓存和压缩可以提高性能
NGINX可以用来提高web应用程序性能的一些附加特性实际上并不属于优化的范畴,但值得一提的是,它们的影响是相当大的。它们包括缓存和压缩。
缓存
通过在NGINX实例上启用缓存(NGINX实例是一组web或应用程序服务器的负载平衡),可以显著提高对客户端的响应时间,同时显著减少后端服务器上的负载。缓存本身就是一个主题,我们不会在这里讨论它。请参阅NGINX Plus管理指南。
压缩
压缩发送到客户端的响应可以大大减小它们的大小,因此它们使用较少的网络带宽。然而,由于压缩数据会消耗CPU资源,因此当确实值得减少带宽使用时,它是最有用的。需要注意的是,不应为已压缩的对象(如JPEG文件)启用压缩。有关更多信息,请参阅NGINX Plus管理指南。