📌 一句话摘要 本文通过五个真实的生产事故案例,系统总结了 Nginx 在高并发场景下的关键配置最佳实践,涵盖日志、WebSocket、容器化、热升级和常见陷阱。 📝 详细摘要 文章以一次大促期间因 Nginx 未配置 keepalive 导致百万损失的 P0 故障为引子,系统梳理了 Nginx 生产环境中的五个关键配置要点和五个真实事故复盘。核心内容包括:自定义日志格式添加响应时间字段以快速定位性能瓶颈;WebSocket 长连接的正确配置(协议升级头、超时时间、负载均衡策略);Docker/K8s 容器中 Nginx 的 CPU 核心数动态注入和 DNS 缓存问题;热升级的正确步骤和
📌 一句话摘要
本文通过五个真实的生产事故案例,系统总结了 Nginx 在高并发场景下的关键配置最佳实践,涵盖日志、WebSocket、容器化、热升级和常见陷阱。
📝 详细摘要
文章以一次大促期间因 Nginx 未配置 keepalive 导致百万损失的 P0 故障为引子,系统梳理了 Nginx 生产环境中的五个关键配置要点和五个真实事故复盘。核心内容包括:自定义日志格式添加响应时间字段以快速定位性能瓶颈;WebSocket 长连接的正确配置(协议升级头、超时时间、负载均衡策略);Docker/K8s 容器中 Nginx 的 CPU 核心数动态注入和 DNS 缓存问题;热升级的正确步骤和 worker_shutdown_timeout 参数;以及五个真实事故(写死 IP 导致 502、证书过期、if 指令导致 404、gzip 乱码、keepalive 未配)的根因分析和最佳实践。文章强调这些坑事后看都很简单,但出事故时没有时间思考,必须提前在配置 review、压测和 checklist 中做好防范。
💡 主要观点
-
Nginx 日志必须包含响应时间字段,否则无法定位性能瓶颈。
默认日志格式缺少 request_time、upstream_connect_time 等关键字段,通过自定义 log_format 添加 rt、uct、uht、urt 四个字段,可快速判断延迟是发生在网络、后端还是连接队列。
WebSocket 长连接需正确配置协议升级头和超时时间,并考虑负载均衡状态问题。
Nginx 默认 proxy_read_timeout 为 60 秒,WebSocket 长连接需调至与心跳间隔匹配;同时必须配齐 Upgrade 和 Connection 头;负载均衡建议后端无状态化(连接上下文存 Redis),而非简单使用 ip_hash。
容器中 Nginx 的 worker_processes auto 会读取宿主机核心数,导致资源浪费和性能下降。
在 Docker/K8s 中,auto 会读取宿主机 /proc/cpuinfo,而非 cgroup 限制。正确做法是在 entrypoint 中用 nproc 动态注入容器实际分配的 CPU 核心数,并用 exec 启动使 Nginx 成为 PID 1 以正确处理信号。
nginx -s reload 对长连接并非完全无损,需配置 worker_shutdown_timeout 并在低峰期操作。
reload 后老 worker 会等待已有连接处理完,但超过 worker_shutdown_timeout 会强制退出,中断长连接。热升级需按 USR2 → WINCH → QUIT 的正确步骤操作,严禁 kill -9 老进程。
Nginx 的 if 指令在 location 块中行为反直觉,应使用 map 替代。
if 在 location 中的行为不可预测,可能导致 POST 请求 404 等诡异问题。按请求属性做流量分发应使用 map 指令,逻辑清晰且行为可预期。
💬 文章金句
- 事故从来不是代码写坏了,往往只是一个参数没配,或者配了个错的。
- 出了性能问题,这种日志等于没有。
- 这些坑,事后看每一个都显而易见。但出事的时候,告警在刷屏、用户在投诉、领导在问,你根本没有时间静下来思考。
- keepalive 不是可选项,是高并发场景的基础配置。
- 配置变更走 Git,不允许直接改生产文件;upstream 写服务发现的域名,不写死 IP。
📊 文章信息
AI 初评:88
来源:dbaplus社群
作者:dbaplus社群
分类:软件编程
语言:中文
阅读时间:17 分钟
字数:4035
标签:
Nginx, 生产事故, 配置最佳实践, 高并发, WebSocket
阅读完整文章