概述
Nginx 配置指令繁多,但直接影响性能的核心指令并不多。在实际部署中,运维团队通常会提供标准配置。除非有特殊的性能需求,我们很少需要调整 Nginx 的默认配置,因为 Nginx 在设计之初就已对性能进行了大量优化。
操作系统层面的考量
事件模型
Nginx 的事件模型应与操作系统相匹配。对于 Linux 2.6 及以上内核,推荐使用 epoll 模型。
文件描述符限制
每个客户端连接都会占用一个文件描述符。可以使用 ulimit -a 命令查看系统限制。在高并发场景下,建议先提高内核级别的限制(如修改 /etc/security/limits.conf),然后在 Nginx 配置中使用 worker_rlimit_nofile 指令来调整单个 worker 进程可打开的最大文件描述符数量。
Nginx 核心性能指令
worker_processes
定义 Nginx worker 进程的数量。默认值为 1。通常建议将此值设置为与服务器 CPU 物理核心数相等。设置过多不仅不会带来显著的性能提升,反而可能因进程调度增加 CPU 开销。如果业务逻辑中包含大量阻塞 I/O 操作,可以适当增加此值。
worker_connections
定义单个 worker 进程同时能够处理的最大连接数。理论上,Nginx 能处理的最大客户端连接数为 worker_processes * worker_connections。一个常见的建议是将此值设置为 (系统文件描述符限制) / worker_processes。考虑到 HTTP 请求的突发性和连接生命周期的差异,实践中可以根据实际情况调整,因为每个文件描述符本身也消耗系统资源。
worker_cpu_affinity
用于将 worker 进程绑定到特定的 CPU 核心上(仅限 FreeBSD 和 Linux)。现代操作系统的进程调度算法已经相当高效,手动绑定 CPU 亲和性通常不会带来显著的性能提升,有时甚至可能适得其反。除非在监控中发现明显的 CPU 负载不均衡问题,否则不建议使用此指令。
sendfile
启用后,Nginx 可以在内核空间直接将文件数据发送到网络套接字,避免了数据在用户态和内核态之间的多次拷贝,能有效降低 CPU 消耗,通常建议开启。网上有建议称在处理大文件(如超过 4MB)时应关闭 sendfile,这可能与早期内核实现或特定场景下的缓冲区限制有关。现代 Linux 内核(2.4+)已支持 sendfile64,对于大文件处理已无此限制。因此,除非遇到特定问题,否则应保持开启。
tcp_nodelay 与 tcp_nopush
这两个指令控制 TCP 套接字的行为,影响数据发送的时机和网络效率。
- tcp_nopush:与
sendfile指令配合使用。它指示操作系统在数据包填满一个 MSS(最大报文段长度)或等待更多数据后再发送,以减少网络中小数据包的数量,提升网络吞吐率。这基于 Nagle 算法。 - tcp_nodelay:禁用 Nagle 算法,允许数据立即发送,减少延迟。这对于需要低延迟的交互式应用(如 WebSocket)很重要。
默认配置下,tcp_nodelay 是开启的,而 tcp_nopush 是关闭的。在 HTTP 场景下,一个常见的优化组合是同时启用 sendfile、tcp_nopush,并在 keep-alive 连接上启用 tcp_nodelay。
keepalive_timeout
设置保持连接的超时时间。启用 HTTP keep-alive 后,客户端可以在一个 TCP 连接上发送多个请求,避免了重复的三次握手,从而提升页面加载速度和用户体验。应根据业务情况设置一个合理的值,避免恶意客户端长时间占用连接。
减少磁盘 I/O
Nginx 的 CPU 和内存使用效率很高,磁盘 I/O 往往是性能瓶颈。应尽量减少不必要的磁盘读写操作。
open_file_cache
缓存打开文件的描述符、大小、修改时间等信息,对于静态文件服务能显著减少重复的 stat() 系统调用。相关指令如 open_file_cache_valid、open_file_cache_min_uses 可用于控制缓存行为。
access_log 与 error_log
- access_log:记录所有访问请求。在高流量下,频繁的日志写入会成为性能瓶颈。如果不需要访问日志进行分析或审计,可以考虑关闭。或者,可以将其写入到更快的存储介质(如内存盘),或使用异步写入。
- error_log:记录错误信息。由于错误请求相对较少,开启它对性能影响通常不大,建议保持开启以便排查问题。
缓冲区大小设置
如果缓冲区设置过小,Nginx 会将无法立即处理的数据写入临时文件,导致磁盘 I/O。
- client_body_buffer_size:设置客户端请求体(如 POST 数据)的缓冲区大小。如果请求体超过此值,数据将被写入临时文件。
- fastcgi_buffers 与 proxy_buffers:设置用于缓存后端(如 PHP-FPM 或上游服务器)返回响应的缓冲区数量和大小。如果响应过大,也会写入临时文件。默认值通常为 8 个 4k 或 8k 的缓冲区(取决于系统内存页大小)。
gzip 压缩
虽然不属于减少磁盘 I/O,但启用 gzip 压缩可以显著减少网络传输的数据量,有效利用带宽,降低延迟。默认压缩级别为 1。不建议设置过高的压缩级别(如 9),因为更高的压缩率带来的收益递减,但 CPU 消耗会显著增加。
其他常见指令
请求头缓冲区
client_header_buffer_size 与 large_client_header_buffers 用于缓存客户端请求头。如果请求头超出限制,Nginx 会返回 400 或 414 错误。通常使用默认值即可,对性能影响不大。
超时设置
- client_body_timeout 与 client_header_timeout:定义读取客户端请求体和请求头的超时时间。用于防止恶意或网络不佳的客户端长时间占用连接。注意,
client_body_timeout指的是两次连续读操作之间的超时,而非整个请求体的传输超时。默认值为 60 秒。 - send_timeout:设置向客户端发送响应的超时时间,同样指两次连续写操作之间的间隔。默认值为 60 秒。
总结
对于大多数应用场景,使用 Nginx 的默认配置并适当调整 worker_processes 和 worker_connections 即可满足需求。其他参数的调整应基于实际的性能监控和分析,针对特定的瓶颈进行优化。在没有明确需求时,过度优化可能收效甚微甚至引入复杂性。
洗手时看见学校食堂师傅炒菜时挖鼻孔手都不洗就继续炒菜,向校长报告,校长说严肃处理,特么的没想到第二天挂了个闲人免进的牌子。 可乐兔是分享正能量,有趣的,有价值故事的网站 欢迎大家访问http://keletu.net/