NGINX作为一个高性能的负载均衡器、缓存和Web服务器,已被全球超过40%最繁忙的网站所使用。对于大多数用例,默认的NGINX和Linux设置已经能够很好地满足需求,但要实现最佳性能,有时需要进行一些调整。本文讨论了在调整系统时需要考虑的一些NGINX和Linux设置。
几乎任何设置都可以调整,但本文专注于那些调整后能带来最大用户收益的设置。有些设置我们建议仅在你对NGINX和Linux有深入理解的情况下调整,或者根据我们的支持团队或专业服务团队的指导进行调整,这些设置我们在这里不做讨论。我们的专业服务团队曾与世界上一些最繁忙的网站合作,调优NGINX以实现最大性能水平,若你希望从NGINX或NGINX Plus部署中获得最大收益,团队可以与您合作。
引言
假设读者对NGINX的架构和配置概念有基本了解。本文并不试图复制NGINX文档,而是提供对各种选项的概述,并链接相关的文档。
调优时的一个好规则是每次只更改一个设置,并且如果更改没有改善性能,则将其恢复为默认值。
我们首先讨论Linux调优,因为某些操作系统设置的值决定了你如何调整NGINX配置。
调优你的Linux配置
现代Linux内核(2.6+)中的设置适用于大多数用途,但调整其中的一些设置可能会带来好处。如果你看到内核日志中有错误消息,指示某个设置值太低,请根据提示调整。这里我们只讨论那些在正常工作负载下最可能受益的设置。有关调整这些设置的详细信息,请参考你的Linux文档。
Backlog队列
以下设置与连接以及它们如何排队有关。如果你有大量的传入连接,并且发现性能不均匀(例如,一些连接似乎在停滞),那么调整这些设置可能会有所帮助。
-
net.core.somaxconn
– 可排队等待NGINX接受的最大连接数。默认值通常很低,通常情况下这样是可以接受的,因为NGINX接受连接非常快速,但如果你的网站流量很大,可以考虑增加这个值。如果内核日志中有错误消息指示该值过小,可以增加该值直到错误停止。注意:如果你将该值设置为大于512,请将NGINX的
listen
指令中的backlog
参数与之匹配。 -
net.core.netdev_max_backlog
– 网络卡在将数据包交给CPU之前缓冲的速率。增加此值可以提高带宽较高的机器的性能。检查内核日志中与此设置相关的错误,并查阅网络卡文档获取关于如何调整该值的建议。
文件描述符
文件描述符是操作系统用于表示连接和打开文件等资源的标识符。NGINX每个连接最多可以使用两个文件描述符。例如,如果NGINX正在进行代理,它通常为客户端连接使用一个文件描述符,为代理的服务器连接使用另一个文件描述符,尽管如果使用HTTP保持连接,这个比例会低很多。对于服务大量连接的系统,可能需要调整以下设置:
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
,这样 NGINX 会自动根据 CPU 核心数进行调整。当工作进程需要进行大量磁盘 I/O 时,可能需要增加该值。 - worker_connections:每个工作进程可以同时处理的最大连接数。默认值为 512,但大多数系统资源足够支持更大的连接数。合适的设置取决于服务器的大小和流量的性质,可以通过测试来确定。
保持连接
保持连接可以显著提高性能,通过减少开启和关闭连接时所需的 CPU 和网络开销。当 NGINX 作为代理时,它终止所有客户端连接,并与上游服务器建立独立的连接。NGINX 支持客户端和上游服务器的保持连接。以下指令与客户端的保持连接相关:
- keepalive_requests:客户端通过单个保持连接可以发送的请求数。默认值为 100,但对于使用负载生成工具进行测试时,设置更高的值会更有用,负载生成工具通常会从单个客户端发送大量请求。
- keepalive_timeout:保持连接空闲时保持打开的时间。
以下指令与上游服务器的保持连接相关:
- keepalive:每个工作进程与上游服务器保持的空闲保持连接数。没有默认值。
要启用对上游服务器的保持连接,您还必须在配置中包含以下指令:
proxy_http_version 1.1;
proxy_set_header Connection "";
访问日志
记录每个请求会消耗 CPU 和 I/O 周期,一种减少影响的方法是启用访问日志缓冲。启用缓冲后,NGINX 会将一系列日志条目缓存在内存中,达到缓冲区大小时一次性写入日志文件,而不是每个日志条目单独进行写操作。
要启用访问日志缓冲,可以将 buffer=size
参数添加到 access_log
指令中;当缓冲区达到指定的大小时,NGINX 会将缓冲区的内容写入日志。如果您希望 NGINX 在特定时间后写入缓冲区,可以添加 flush=time
参数。当两个参数都设置时,NGINX 会在下一个日志条目无法容纳在缓冲区中,或者缓冲区中的日志条目超过指定时间时写入日志文件。如果工作进程正在重新打开日志文件或关闭时,日志条目也会被写入。要完全禁用访问日志,可以将 off
参数添加到 access_log
指令中。
Sendfile
操作系统的 sendfile()
系统调用可以在文件描述符之间复制数据,通常可以实现零拷贝,进而加速 TCP 数据传输。要让 NGINX 使用 sendfile()
,请在 http
上下文或 server
、location
上下文中包含 sendfile
指令。启用后,NGINX 可以通过 socket 将缓存的或磁盘上的内容写入,而无需切换到用户空间,极大提高写入速度并减少 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 攻击中的机器人)压垮应用。 - max_conns(上游配置块中的
server
指令): 设置上游组中每个服务器可以接受的最大并发连接数。设置限制有助于防止上游服务器过载。设置为 0(默认值)表示没有限制。 - queue(NGINX Plus):当上游组中的所有服务器都达到
max_conns
限制时,创建一个队列来存放请求。此指令设置队列中请求的最大数量,并可以选择设置最大等待时间(默认 60 秒)。如果未设置此指令,请求将不会被排队。
缓存和压缩可以提高性能
NGINX 的一些其他功能有助于提高 Web 应用程序的性能,这些功能虽然不完全属于调优范畴,但它们的影响不可小觑,包括缓存和压缩。
缓存
通过在负载均衡的 Web 或应用服务器上启用缓存,您可以显著改善客户端的响应时间,同时显著减轻后端服务器的负担。缓存是一个独立的主题,我们不打算在这里深入讨论。请参阅 NGINX Plus 管理员指南。
压缩
将响应压缩后发送给客户端可以显著减少数据大小,从而减少网络带宽的使用。然而,由于压缩数据会消耗 CPU 资源,因此只有在大幅度减少带宽使用时才真正有意义。需要注意的是,您不应对已经压缩的对象(例如 JPEG 文件)启用压缩。更多信息,请参见 NGINX Plus 管理员指南。
结语
要了解更多信息,您可以查看以下资源:
- NGINX 性能基准测试:更高精度和有意义的结果(按需网络研讨会)
- NGINX 参考文档:nginx.org
- NGINX Plus 技术规格
如果您想试用 NGINX Plus,可以开始免费的 30 天试用,或联系我们进行演示。
阅读更多关于 F5 NGINX 的博客文章。
免责声明:此博客文章可能提到的一些产品已经停产或不再支持。如需了解最新的 F5 NGINX 产品和解决方案,请访问 NGINX 产品家族。NGINX 现在是 F5 的一部分,所有以前的 NGINX.com 链接将重定向到 F5.com 上类似的 NGINX 内容。
这篇文章是对 NGINX 调优和相关设置的全面讲解,希望能帮助您根据自己的使用场景进行相应的优化。
NGINX性能优化
NGINX 作为一个高性能的 Web 服务器、负载均衡器和反向代理服务器,以其出色的性能、可扩展性和灵活性而闻名。但要实现最佳性能,需要根据你的具体使用场景进行适当的配置调整。以下是优化 NGINX 性能的几种策略:
1. 工作进程和连接数设置
NGINX 使用工作进程来处理客户端请求,工作进程的数量和配置会极大影响性能。
-
worker_processes: 这个设置决定了 NGINX 将启动多少个工作进程。通常建议设置为机器的 CPU 核心数,可以使用
auto
来让 NGINX 自动检测可用的核心数。worker_processes auto;
-
worker_connections: 这个设置定义了每个工作进程能够同时处理的连接数。默认值为 1024,但对于高流量网站,可以增加此值以处理更多的并发连接。
worker_connections 1024;
计算:
NGINX 可以处理的总连接数是worker_processes * worker_connections
。例如,如果设置了4 worker_processes
和1024 worker_connections
,NGINX 就可以处理4096
个并发连接。 -
use epoll(Linux系统):
epoll
是 Linux 下的一种高效的 I/O 事件通知机制,专为需要处理大量连接的高性能应用设计。默认情况下,NGINX 会在 Linux 系统上启用epoll
,你可以显式地配置以确保最佳性能。events { use epoll; }
2. Keep-Alive 设置
Keep-Alive 连接可以保持客户端和服务器之间的连接开启,用于处理多个请求,减少每次请求时建立新连接的开销。
-
keepalive_timeout: 定义请求完成后连接保持开启的时间。较长的保持时间适用于多次请求的应用,但可能会消耗更多资源。
keepalive_timeout 65;
-
keepalive_requests: 定义一个连接可以处理的最大请求数。增加这个值有助于减少多次请求时的开销。
keepalive_requests 100;
-
proxy_http_version 和 proxy_set_header Connection(反向代理时):确保这些头部设置正确,以便 NGINX 能够保持与上游服务器的持久连接。
proxy_http_version 1.1; proxy_set_header Connection "";
3. 文件缓存
缓存可以显著减少后端服务器的负担,提高响应速度。NGINX 提供了多种缓存选项,可以配置。
-
sendfile: 启用
sendfile
可以让 NGINX 使用sendfile()
系统调用直接从磁盘传输文件到网络套接字,优化数据传输性能。sendfile on;
-
tcp_nopush: 当设置为
on
时,NGINX 会尝试将响应头和数据打包成一个数据包发送,减少响应数据包的数量。tcp_nopush on;
-
tcp_nodelay: 禁用 Nagle 算法,该算法会延迟发送小数据包以积累更多数据,减少低延迟连接的开销。
tcp_nodelay on;
-
open_file_cache: 用于缓存文件描述符,减少文件查找的开销,特别适合静态文件的服务。
open_file_cache max=1000 inactive=20s;
4. 压缩
使用压缩可以减小从服务器到客户端传输的数据量,提升大文件内容的响应速度。
-
gzip: NGINX 支持对文本内容(如 HTML、CSS、JavaScript)进行 GZIP 压缩。可以通过以下设置启用 GZIP 压缩。
gzip on; gzip_types text/plain text/css application/javascript application/json; gzip_min_length 256;
gzip_types
: 指定要压缩的 MIME 类型。gzip_min_length
: 设置响应数据的最小大小(以字节为单位),小于此大小的响应不进行压缩。
5. 限速和连接限制
限制过高的流量可以避免单一客户端占用过多的资源,保证资源的公平分配。
-
limit_conn: 限制每个客户端的连接数。对于某些高流量客户端,可以通过此设置限制每个 IP 地址的并发连接数。
limit_conn addr 10;
这将限制每个 IP 地址最多 10 个并发连接。
-
limit_req: 限制请求的速率,以防止 DoS 攻击或滥用。
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s; limit_req zone=mylimit burst=5;
这设置了每秒 10 个请求的速率,并允许最多 5 次请求的突发流量。
6. 负载均衡与上游服务器调优
如果 NGINX 作为反向代理或负载均衡器使用,调优上游服务器的设置对于高效处理请求非常重要。
-
upstream: 可以定义一个
upstream
块来实现负载均衡,将流量分发到多个后端服务器。支持多种负载均衡算法,如round-robin
(轮询)、least_conn
(最少连接数)等。upstream backend { server backend1.example.com; server backend2.example.com; server backend3.example.com; }
-
max_fails 和 fail_timeout: 这些设置控制了当上游服务器连接失败时,NGINX 如何处理失败的连接。指定最大失败次数以及失败后的超时时间,超过最大失败次数后,NGINX 会暂时从负载均衡池中移除该服务器。
upstream backend { server backend1.example.com max_fails=3 fail_timeout=30s; server backend2.example.com max_fails=3 fail_timeout=30s; }
7. 访问日志与缓冲
过多的日志记录可能会影响性能,特别是在高流量的环境中。你可以通过以下设置来优化访问日志:
-
log_format: 定义自定义日志格式,仅记录必要的信息,减少不必要的日志记录开销。
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
-
access_log: 可以禁用访问日志,或者将日志缓存在内存中,以减少磁盘 I/O。
access_log /var/log/nginx/access.log main buffer=32k;
这将缓冲日志条目,减少磁盘写入。
8. SSL/TLS 优化
SSL/TLS 加密会影响性能,因为它涉及加密操作。为了优化 SSL/TLS 设置,可以考虑以下配置:
-
ssl_session_cache: 启用 SSL 会话缓存,提升客户端重用连接时的性能。
ssl_session_cache shared:SSL:10m;
-
ssl_ciphers: 使用现代的安全加密套件,平衡安全性和性能。
ssl_ciphers 'TLSv1.2:TLSv1.3';
结论
NGINX 本身具备非常高的性能,但其性能很大程度上取决于配置。通过调整工作进程、Keep-Alive 设置、缓存、压缩以及负载均衡等多个方面,可以根据具体的工作负载优化 NGINX 实例,确保资源使用效率最大化。
定期监控 NGINX 性能,并根据实际的流量模式和应用需求进行配置调整,确保从 NGINX 获得最大性能并保持资源的合理利用。