nginx ssl证书更新本身不中断连接,真正导致中断的是reload时旧worker过早退出;必须配置worker_shutdown_timeout(如30s)并协同调优keepalive_timeout、proxy_read_timeout等参数,同时确保证书权限为600、链完整、路径正确且配置在server块内,才能实现零中断。

Nginx SSL 证书更新本身不会中断连接,真正造成“短暂中断”的,是 nginx -s reload 后旧 worker 进程过早退出,导致还在传输中的请求被 RST 重置。只要配对调整几个关键参数,就能实现用户无感的平滑切换。
必须配置 worker_shutdown_timeout
这是控制是否中断的核心开关,但默认值为 0(即不等待),必须手动启用:
- 在
http{}或main{}块中添加:worker_shutdown_timeout 30s; - 它表示旧 worker 收到 QUIT 信号后,最多再服务 30 秒——期间继续处理已有连接的请求,但不再接受新连接
- 设太短(如 5s)可能截断慢响应;设太长(超过后端最长响应时间)会让 worker 卡住,建议略大于
proxy_read_timeout
同步调优三类关联超时
单靠 worker_shutdown_timeout 不够,上下游时间窗口必须匹配:
-
keepalive_timeout设为 ≥60s:防止 reload 前复用连接被 Nginx 主动关闭 -
proxy_read_timeout和proxy_send_timeout必须 ≥worker_shutdown_timeout:否则旧 worker 可能因代理超时提前退出,丢弃未发完的响应 -
ssl_session_timeout建议设为 4h:不影响 reload,但有助于客户端复用 TLS 会话,减少握手开销
确保证书文件一次到位
reload 成功 ≠ 新证书生效,常见静默失败原因包括:
- 私钥权限不是 600(如误设为 644),Nginx 会静默降级回用旧证书
- 证书链不完整(只放了
domain.crt,没合并中间证书),部分 Android 或旧 iOS 客户端会校验失败 -
ssl_certificate写在server块之外(例如放在http块中),Nginx 将忽略该配置 - 路径写错或文件不存在,新 worker 启动失败,主进程自动回退——日志显示 reload 成功,实则证书未更新
验证是否真零中断,不能只看日志
执行 nginx -s reload 后,要实测连接生命周期:
- 用
ss -tnp | grep :443观察 ESTAB 连接数,reload 前后应平滑过渡,不应归零 - 对 WebSocket 长连接持续 ping,确认 reload 期间无 1006 错误
- 抓包检查是否有突现的 RST 包;或查 error log 中是否出现
shutdown() failed或recv() failed - 用
openssl s_client -connect yoursite.com:443 -servername yoursite.com 2>/dev/null | openssl x509 -noout -dates确认指纹已是新证书











