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