Nginx高性能配置需三类参数协同校准:资源调度(worker_processes auto与worker_connections 4096需匹配ulimit -n≥65535)、传输优化(sendfile/tcp_nopush/tcp_nodelay组合启用且依赖epoll)、防护与可观测性(add_header ... always、server_tokens off置于http顶层、日志含$request_time和$upstream_response_time)。

直接用一套结构清晰、分层明确的标准化配置,比零散堆参数更可靠。关键不是“全开”,而是三类参数协同校准:资源调度、传输优化、防护与可观测性,并同步匹配系统级限制。
worker_processes 和 worker_connections 怎么设才不翻车
这两个值不是越大越好,错配会触发 accept() failed (24: Too many open files) 或 CPU 空转。必须一起调:
• worker_processes auto 是安全起点,容器环境可显式设为 2 或 4 避免争抢
• worker_connections 4096 要求系统级 ulimit -n 至少为 65535(即 4 × 4096 × 4 留出余量)
• 在 /etc/security/limits.conf 里加两行:nginx soft nofile 65535 和 nginx hard nofile 65535,否则重启后失效
• 不要盲目写 worker_cpu_affinity,除非你真在裸金属上跑且压测证明有收益
sendfile / tcp_nopush / tcp_nodelay 组合为什么不能拆开用
这三个是 TCP 传输链路上的协同开关,单独启用某个反而可能劣化:
• sendfile on 启用内核零拷贝,但若没配 tcp_nopush on,小响应会被拆成多个小包发出去
• tcp_nopush on 必须配合 sendfile 才生效,它只对 sendfile 场景做包合并
• tcp_nodelay on 是对非 sendfile 场景(比如动态内容)的兜底,禁用 Nagle 算法避免延迟累积
• Linux 下必须配 use epoll,否则 tcp_nopush 和 multi_accept on 都无效
安全头和日志字段怎么加才真正可审计
光加 add_header 不够,很多头默认不继承到子 location,容易漏防:
• 用 always 参数确保所有响应都带:add_header X-Content-Type-Options "nosniff" always
• server_tokens off 必须放在 http 块顶层,否则某些 error_page 仍会暴露版本
• 日志格式里至少补上 $request_time 和 $upstream_response_time,否则无法区分是 Nginx 卡还是后端慢
• 不要用 if 做 IP 白名单,改用 allow/deny 直接写在 location 里,if 在 location 中有已知重入风险
HTTPS 强制跳转和 uWSGI 通信配置最容易被忽略的细节
这两处一错,服务就不可用,但错误日志往往不报具体原因:
• HTTP 跳 HTTPS 的 return 301 https://$host$request_uri 必须配在独立的 server { listen 80; } 块里,不能塞进 HTTPS server 块内
• uWSGI socket 权限要严格:chown-socket = myappuser:www-data + chmod-socket = 660,Nginx 进程需属 www-data 组才能连上
• proxy_set_header Host $host 和 proxy_set_header X-Real-IP $remote_addr 缺一不可,否则 Django/Flask 拿不到真实 IP 和 Host
• proxy_buffering off 在调试阶段建议打开,避免长响应被缓冲掩盖超时问题
真正的难点不在单个指令,而在它们之间的约束关系——比如改了 worker_connections 就得立刻验证 ulimit,开了 sendfile 就得确认 tcp_nopush 是否生效。每次变更后必须跑 nginx -t + curl -I 看响应头 + ab 或 wrk 压测连接数,缺一不可。











