Nginx 性能优化
从通用优化、操作系统层、Nginx 配置层、架构层等多个维度,为你详细梳理的方式。
一、操作系统与硬件层优化
这是优化的基础,为 Nginx 提供一个高性能的运行环境。
增加文件描述符限制 Nginx 每个连接(尤其是静态文件)都会消耗一个文件描述符。如果并发高,默认限制很容易成为瓶颈。
# 临时生效 ulimit -n 65536 # 永久生效,修改 /etc/security/limits.conf * soft nofile 65536 * hard nofile 65536 # 同时,确保 nginx.conf 中使用了足够的 worker_rlimit_nofile worker_rlimit_nofile 65536;优化网络栈
- 调整
net.core.somaxconn: 定义等待 Nginx 接受的最大连接队列长度。如果遇到accept()队列溢出的错误,需要增加这个值。并在 Nginx 的sysctl -w net.core.somaxconn=65535listen指令中显式指定backlog参数:listen 80 backlog=65535; - 启用 TCP Fast Open: 减少 TCP 三次握手的延迟。
sysctl -w net.ipv4.tcp_fastopen=3 - 增大临时端口范围: 当 Nginx 作为反向代理时,它需要大量本地端口来连接上游服务器。
sysctl -w net.ipv4.ip_local_port_range="1024 65535" - 减少 TCP TIME_WAIT 状态: 对于高并发短连接场景,大量连接处于 TIME_WAIT 状态会耗尽端口资源。
# 启用 TIME_WAIT 复用 sysctl -w net.ipv4.tcp_tw_reuse=1 # 快速回收 TIME_WAIT 连接 sysctl -w net.ipv4.tcp_tw_recycle=0 # 注意:在 NAT 环境下建议为 0,否则可能有问题 # 增大 FIN_WAIT_2 状态的超时时间 sysctl -w net.ipv4.tcp_fin_timeout=30
- 调整
使用高性能磁盘 对于静态资源服务,使用 SSD 硬盘可以极大提升 IO 性能。
二、Nginx 配置优化
这是优化的核心,直接决定 Nginx 的行为。
工作进程与连接数
worker_processes auto;: 设置为auto,让 Nginx 自动根据 CPU 核心数设置工作进程数,通常等于 CPU 核心数。worker_connections: 每个工作进程可以处理的最大连接数。它与worker_rlimit_nofile共同决定了 Nginx 的总并发能力。events { worker_connections 10240; # 例如,设置为 10240 use epoll; # 在 Linux 上使用高性能的 epoll 事件模型 }
高效静态资源服务
- 启用
sendfile: 绕过用户空间,直接在内核中完成文件数据传输,非常高效。sendfile on; - 启用
tcp_nopush: 与sendfile on一起使用,确保数据包被填满后再发送,提高网络效率。tcp_nopush on; - 启用
tcp_nodelay: 针对 keepalive 连接,强制立即发送数据,减少延迟。通常与tcp_nopush一起使用。tcp_nodelay on;
- 启用
连接与请求超时 合理的超时设置可以释放闲置资源,避免连接被长期占用。
# 客户端连接保持超时时间 keepalive_timeout 30s; # 与上游服务器的保持连接超时时间 proxy_connect_timeout 5s; proxy_send_timeout 60s; proxy_read_timeout 60s; # 客户端请求头读取超时 client_header_timeout 15s; # 客户端请求体读取超时 client_body_timeout 15s;缓冲与缓存
- 缓冲区优化: 为客户端请求头和请求体设置合适的缓冲区大小,避免 Nginx 写入临时文件,降低 IO。
client_header_buffer_size 1k; large_client_header_buffers 4 4k; client_body_buffer_size 128k; - 代理缓冲区: 当 Nginx 作为反向代理时,控制从上游服务器接收数据的缓冲区。
proxy_buffering on; proxy_buffer_size 4k; proxy_buffers 8 4k; - 启用缓存:
- 静态资源缓存: 使用
expires或add_header指令为静态资源设置长时间的浏览器缓存。location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { expires 1y; add_header Cache-Control "public, immutable"; } - 反向代理缓存: 使用
proxy_cache模块缓存上游服务器的动态内容,极大减轻后端压力。proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m; location / { proxy_cache my_cache; proxy_cache_valid 200 302 10m; proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; }
- 静态资源缓存: 使用
- 缓冲区优化: 为客户端请求头和请求体设置合适的缓冲区大小,避免 Nginx 写入临时文件,降低 IO。
日志优化
- 禁用访问日志: 对于极高并发且不关心访问日志的场景,可以关闭
access_log。 - 缓冲写入日志: 使用
buffer参数让 Nginx 先将日志写入内存缓冲区,满后再刷入磁盘。access_log /var/log/nginx/access.log main buffer=64k flush=1m; - 记录关键信息: 精简日志格式,只记录必要字段。
- 禁用访问日志: 对于极高并发且不关心访问日志的场景,可以关闭
Gzip 压缩 对文本类型的响应进行压缩,减少网络传输量。
gzip on; gzip_vary on; gzip_min_length 1024; # 小于此值不压缩 gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;上游连接保持 当代理到后端服务时,使用
keepalive保持一定数量的空闲连接,避免频繁建立和断开 TCP 连接的开销。upstream backend_servers { server 10.0.1.100:8080; keepalive 32; # 保持的空闲连接数 } location / { proxy_pass http://backend_servers; proxy_http_version 1.1; proxy_set_header Connection ""; }
三、架构与部署优化
负载均衡 使用 Nginx 的
upstream模块将流量分发到多个后端服务器,实现水平扩展和高可用。upstream app_cluster { least_conn; # 使用最少连接算法 server 10.0.1.101:8080; server 10.0.1.102:8080; server 10.0.1.103:8080; }动静分离 将静态资源(图片、CSS、JS)的请求与动态请求分开。可以让 Nginx 直接处理静态资源,而动态请求则代理给后端应用服务器(如 Tomcat, Node.js 等)。
启用 HTTP/2 HTTP/2 提供了多路复用、头部压缩等特性,能显著提升页面加载速度。
listen 443 ssl http2;使用第三方模块 根据需求编译第三方模块,如:
- OpenResty: 基于 Nginx 和 LuaJIT,提供了强大的可编程能力。
- ngx_brotli: 使用 Brotli 压缩算法,通常比 Gzip 压缩率更高。
四、监控与调试
优化不是一次性的,需要持续监控。
启用状态模块 使用
stub_status_module来查看 Nginx 的基本状态信息。location /nginx_status { stub_status; allow 127.0.0.1; # 只允许本机访问 deny all; }访问后可以看到活跃连接数、请求总数等信息。
分析日志 使用工具如
goaccess、awstats分析访问日志,了解流量模式和瓶颈。性能剖析 在极端情况下,可以使用
debug日志或系统工具(如perf,strace)进行深度性能剖析。
总结与建议
- 循序渐进: 不要一次性修改所有参数。一次只修改一两项,然后进行压测(如使用
wrk,ab,jmeter),观察效果。 - 监控先行: 在优化前、中、后都要有可靠的监控数据作为依据。
- 理解业务: 优化的策略很大程度上取决于业务类型。是高并发连接?是大文件下载?还是大量的短动态请求?
- 内核参数谨慎调整: 生产环境调整内核参数前,务必在测试环境充分验证。
通过以上这些方式的组合运用,你可以显著提升 Nginx 的性能和稳定性,使其能够轻松应对百万级别的并发连接。