Nginx 性能优化:提升网站速度的技巧
通过我们全面的性能优化指南,释放您的 Nginx 服务器的全部潜力。学习如何微调工作进程、实施强大的缓存策略、启用高效压缩(Gzip/Brotli)以及优化连接处理。本文提供了实用的 Nginx 配置技巧和最佳实践,以大幅减少加载时间、改善用户体验,并提升您网站的整体速度和效率。对于寻求巅峰性能的系统管理员和 Web 开发人员来说,这是必读内容。
Nginx性能优化:打造更快网站的实用技巧
网站速度慢通常源于几个原因:昂贵的上游响应、缺少缓存头、资源过大、工作进程阻塞,或者服务器配置仅采用默认值而非针对流量优化。Nginx性能优化最佳实践是:先测量,一次只改一个设置,并保持配置清晰可读。
以下示例可作为起点,然后针对你自己的应用进行负载测试。静态文件服务器、WordPress/PHP-FPM站点和API反向代理需要不同的权衡策略。
理解Nginx性能瓶颈
首先找到瓶颈。常见原因包括:
- CPU使用率: 高CPU负载会拖慢请求处理、压缩和TLS工作。
- 内存压力: 交换会严重损害延迟。
- 网络I/O: 慢速链路、小的上游窗口或丢包可能主导响应时间。
- 磁盘I/O: 静态文件、缓存文件和日志仍会触及存储。
- 上游延迟: Nginx可能很快,但你的应用服务器可能很慢。
top、htop、iostat、ss、访问日志和Nginx的stub_status模块等工具可以帮助你决定调整什么。
核心Nginx优化技术
工作进程和连接数
worker_processes指令控制Nginx启动的工作进程数量。auto是一个实用的默认值,因为Nginx会检测可用的CPU核心。
# 将worker_processes设置为CPU核心数
worker_processes auto;
在每个工作进程内,worker_connections限制该工作进程可以打开的同时连接数。粗略上限是worker_processes * worker_connections,但实际容量还取决于上游连接、打开文件限制、keep-alive行为和操作系统限制。
# 为高流量站点增加worker_connections
worker_connections 1024;
如果看到Too many open files,仅提高worker_connections是不够的。还需要检查服务的文件描述符限制,通常由systemd的LimitNOFILE或shell限制控制。
缓存策略
缓存通常是影响最大的Nginx性能优化,因为它可以避免重复工作。
浏览器缓存
告诉浏览器缓存版本化的静态资源,如图片、CSS和JavaScript。仅在部署时文件名发生变化(如app.8f3c1.css)的情况下使用长缓存时间。
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public";
}
代理缓存
如果Nginx是反向代理,它可以缓存选定的后端响应。这适用于公共页面、具有明确新鲜度规则的API响应以及不因用户而变化的昂贵页面。
首先,在http块中定义缓存区域:
http {
# ... 其他http配置 ...
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m;
# ...
}
/var/cache/nginx:缓存文件存储的目录。levels=1:2:定义缓存的目录结构。keys_zone=my_cache:10m:创建一个名为my_cache的共享内存区域,大小为10MB,用于存储缓存键。max_size=1g:设置缓存的最大大小。inactive=60m:移除60分钟内未被访问的缓存条目。
然后,在location块中启用缓存:
location / {
proxy_pass http://your_backend_app;
proxy_cache my_cache;
proxy_cache_valid 200 302 10m; # 缓存200和302响应10分钟
proxy_cache_valid 404 1m; # 缓存404响应1分钟
add_header X-Cache-Status $upstream_cache_status;
}
add_header X-Cache-Status $upstream_cache_status; 对调试很有用,可以显示请求是缓存命中、未命中还是绕过。
不要缓存个性化页面,除非你的缓存键考虑了改变响应的数据。例如,登录后的仪表板通常应绕过代理缓存,而/assets/logo.png可以长时间缓存。
压缩
压缩可以减少基于文本的响应(如HTML、CSS、JavaScript、JSON和XML)的传输大小。对于已经压缩的文件(如JPEG、PNG、MP4或许多归档格式),压缩帮助不大。
http {
# ...
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# ...
}
gzip on;:启用Gzip压缩。gzip_vary on;:添加Vary: Accept-Encoding头,这对缓存代理很重要。gzip_proxied any;:也对代理请求的响应进行压缩。gzip_comp_level 6;:设置压缩级别(1-9,越高压缩越好但CPU消耗越大)。gzip_types ...;:指定要压缩的MIME类型。
Brotli可以很好地压缩文本资源,但标准的开源Nginx构建并不都支持Brotli。在添加Brotli指令之前,请检查你的软件包或模块集。
连接处理和Keep-Alive
keepalive_timeout指令控制空闲客户端连接保持打开的时间。重用连接可以避免额外的TCP和TLS握手,但空闲连接仍会消耗资源。
http {
# ...
keepalive_timeout 65;
keepalive_requests 1000;
# ...
}
keepalive_timeout 65;:将keep-alive超时设置为65秒。keepalive_requests 1000;:设置单个keep-alive连接上可以处理的最大请求数。
对于有许多短请求的API,keep-alive很有帮助。对于有许多空闲客户端的小型服务器,较短的超时可能更好。
缓冲和请求大小限制
Nginx使用缓冲区来处理客户端请求体和代理响应。默认值对许多站点来说没问题,但上传密集型应用和大的上游头可能需要显式设置。
http {
# ...
client_body_buffer_size 10K;
client_max_body_size 8M;
proxy_buffers 8 16k;
proxy_buffer_size 16k;
proxy_connect_timeout 60;
proxy_send_timeout 60;
proxy_read_timeout 60;
# ...
}
client_body_buffer_size:用于读取客户端请求体的缓冲区大小。client_max_body_size:客户端请求体的最大允许大小。proxy_buffers、proxy_buffer_size:控制Nginx作为代理时的缓冲。
避免盲目复制缓冲区设置。如果看到upstream sent too big header,在提高proxy_buffer_size之前先调查上游头。如果上传失败并显示413 Request Entity Too Large,将client_max_body_size设置为你的应用实际支持的大小。
TLS优化
对于HTTPS站点,TLS设置会影响延迟和安全性。
- 会话恢复: 使用会话缓存来加速重复连接。
ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_session_tickets off; - TLS版本: 除非兼容性要求另有规定,否则启用TLS 1.2和TLS 1.3。
- OCSP装订: 当证书链支持时,可以减少证书验证的往返次数。
ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s;
静态文件服务
Nginx擅长提供静态文件。这些指令在http块中很常见:
sendfile: 允许内核在支持的系统上直接将文件数据复制到套接字。sendfile on;tcp_nopush和tcp_nodelay: 针对常见HTTP工作负载调整数据包发送行为。tcp_nopush on; tcp_nodelay on;
监控和测试
每次更改后,进行测试和比较。有用的工具包括:
- Nginx
stub_status: 活动连接、接受的连接、处理的连接和请求数。 top/htop: CPU和内存压力。iostat: 磁盘I/O。- WebPageTest或PageSpeed Insights: 浏览器端性能。
wrk、ab或hey: 针对受控端点的本地负载测试。
保留先前配置的副本,运行sudo nginx -t,重新加载,然后比较延迟、错误率、CPU和上游响应时间。最好的Nginx性能优化是你的测量结果能够证明的优化。
实用要点
从测量开始,然后首先修复最大的瓶颈。对于大多数网站来说,这意味着设置合理的工作进程限制、为静态资源添加浏览器缓存、启用gzip、缓存安全的上游响应,并在每次重新加载后监控日志。