Nginx reload 不是重启,线上别把 reload 当成无风险操作
当前位置:点晴教程→知识管理交流
→『 技术文档交流 』
晚上业务高峰,应用同事说要加一条转发规则,理由也很简单:“这不是重启,reload 一下就行,不会有事。” 结果命令打完,监控里 499、502 开始抖,少量长连接被打断,报警群一下热闹起来。最后查下来,Nginx 确实没“重启”,进程也还在,但线上还是被 reload 弄出了波动。 这个事很多团队都遇到过。问题不在于 reload 能不能用,而在于很多人把它理解成了“绝对无感、绝对安全”。这就容易出事。 先说现象:为什么明明只是 reload,线上还是会抖 Nginx 的 reload,本质上是让 master 进程重新加载配置,然后拉起新 worker,老 worker 再慢慢退出。它不是暴力停服务,所以大家才会说它是“平滑”的。 但“平滑”不等于“零影响”。生产上常见的抖动,基本就这几类: • 少量请求失败:尤其在高并发、高连接数的时候,切换窗口里更容易出现。 • 长连接受影响:WebSocket、流式接口、长时间上传下载,最容易踩坑。 • 配置生效后行为变了:比如 upstream、超时、限流、缓存、header 规则变更,业务体感比你想象的大。 • worker 迟迟退不掉:老连接不释放,导致进程堆着,内存和 fd 压力上来。 所以线上看到 reload 后有波动,不一定是 Nginx “坏了”,而是这个动作本来就会触发连接切换和进程回收。 很多人的第一反应,为什么不一定对 常见误区有三个。 第一,把 reload 理解成单纯“让配置文件重新读一遍”。实际上它涉及新老 worker 交替,不是编辑器点个刷新那么简单。 第二,觉得只要 nginx -t 通过就万事大吉。语法通过,只代表配置能解析,不代表流量切换一定没影响。比如 upstream 权重改错、keepalive 配置不合理、超时参数改小,都是“能过语法但会影响线上”的典型。 第三,觉得 reload 比 restart 安全,所以可以频繁做。这在测试环境可能没感觉,在生产高峰期就不一样了。你每 reload 一次,就相当于让 worker 做一次切换。变更越频繁,风险窗口越多。 经验上,reload 不是不能做,而是不能把它当成“无成本操作”。 ![]() 真正原因:问题通常不在命令本身,而在连接和配置变化 很多线上事故,表面看是 reload 后出问题,实际是下面几种原因叠加。 1. 老 worker 退出没你想得那么快。 如果机器上有很多 keepalive、长连接、慢请求,老 worker 会继续处理手里的连接,直到结束才退出。这个过程里,新老 worker 同时存在,资源占用会变高。 2. 配置变化会直接改变请求路径。 比如 upstream 切换、DNS 解析变化、证书更新、限流规则上线,reload 之后请求就按新规则走了。你以为只是“生效一下”,其实是把线上流量切到另一套逻辑。 3. 高峰期系统本来就紧。 CPU、连接数、文件描述符、后端服务线程池,可能都在边缘。reload 带来的切换成本不大,但刚好压在临界点上,就会被放大成报警。 4. 某些模块或外部依赖会放大抖动。 比如依赖后端域名解析、共享内存区、日志切割、Lua/OpenResty 逻辑、证书文件读取,这些都可能让 reload 不是一句“平滑”就能带过去。 排查别急着猜,先按顺序看 线上碰到 reload 后抖动,别先忙着回滚配置,也别先甩锅网络。建议按这个顺序看。 先确认 reload 到底有没有成功: nginx -s reload ps -ef | grep nginx 如果语法没问题,再看 error log 里有没有关键信息,比如 worker 退出异常、连接关闭、upstream 不可达、证书加载失败。 然后看进程切换情况。正常情况下,会看到新 worker 拉起,老 worker 逐步退出。如果老 worker 长时间不退,说明它手里还有连接,或者某些请求根本结束不了。 ![]() ss -tanp | grep nginx 接着看监控,不要只盯 Nginx。要一起看: • QPS 有没有明显尖刺或掉下去 • 499、502、504 有没有同步增加 • 活跃连接数、TIME_WAIT、CLOSE_WAIT 有没有异常 • 后端应用的线程池、连接池、响应时间有没有抖 如果 reload 后是业务规则变了,就对比变更前后的配置差异,而不是只看 Nginx 进程状态。很多时候进程完全正常,问题是配置逻辑把流量导错了。 生产环境怎么处理:先做什么,再做什么,最后做什么 先做什么:先校验、先 diff、先选时机。不要上来就 reload。 nginx -T > /tmp/nginx.current.conf 把这次变更和当前生效配置做对比,确认到底改了什么。尤其是 upstream、location、rewrite、限流、超时、证书这几块,要重点看。高峰期能不动就别动,必须变更也优先灰度。 再做什么:先在一台边缘节点或低流量节点验证,再逐步扩。不要全量机器一起 reload。哪怕没有完整发布系统,也可以手工分批,一批一批观察 5 到 10 分钟。 最后做什么:观察老 worker 是否退出、错误码是否抖动、后端是否有连带告警。如果发现老 worker 堆积,别急着 kill。强杀可能直接把还在处理的连接打断,影响更大。先判断是不是长连接、慢请求或者后端卡住导致的。 线上正确姿势不是“reload 一下试试”,而是“先验证,再小范围生效,再观察,再继续”。 有些参数别乱改,副作用比想象中大 比如有人为了让老 worker 早点退出,会去动超时参数,或者缩短连接保持时间。这样做不是不行,但副作用要清楚: • keepalive 改小,后端连接复用会变差,可能让应用连接数飙高。 • 超时改小,慢请求会更容易失败,499、504 可能上升。 • worker 数量、连接数乱调,可能让上下游一起抖。 • 直接 kill 老 worker,长连接和正在传输的请求可能被硬切断。 所以生产上最怕的不是“一个 reload”,而是 reload 出现问题后,大家开始连环改参数,越改越乱。 长期治理:别把风险都留在变更当晚 如果团队经常要改 Nginx,靠人肉谨慎是不够的,还是要做治理。 开发侧要关注长连接、超时、重试和幂等。因为 reload 期间最容易暴露的,就是请求中断后应用能不能兜住。 运维侧要把配置校验、diff、分批发布、回滚、监控观察做成固定动作。最好能做到变更前自动检查,变更后自动看关键指标。 架构侧要减少单点入口的硬切换风险。比如多节点分批、入口层灰度、后端摘流量再变更,而不是把所有风险压在一台 Nginx 上。 还有一个很实用的建议:把“什么变更可以直接 reload,什么变更必须走灰度”提前写清楚。证书续期、普通 header 调整,和 upstream 切换、限流变更,风险根本不是一个级别,不要一视同仁。 Nginx reload 的确不是重启,但也绝对不是无风险按钮。它之所以常被低估,是因为大多数时候它看起来很平滑,可一旦碰上高峰流量、长连接、配置逻辑变化,影响就会被放大。 记住一句就够了:线上 reload 可以做,但要把它当成一次正式变更,而不是随手执行的命令。 先校验,再灰度,再观察,最后再全量,这比争论“reload 算不算重启”更重要。 阅读原文:https://mp.weixin.qq.com/s/roAsWDz29V0bMeCDjEld-Q 该文章在 2026/5/16 10:29:55 编辑过 |
关键字查询
相关文章
正在查询... |