某美国服务器Nginx 服务反复停止:排查与修复记录

    环境:Windows Server 2012 R2 + 宝塔 Windows 面板,单机承载约 60 个站点(生产环境)

    现象:在面板修改站点设置后,Nginx 反复显示「已停止」,期间全站不可用

    结论:服务未配置失败恢复动作,停掉后无人接管;已通过 SCM 恢复动作修复

    编写日期:2026-11-04(已隐去服务器地址、账号、密码、域名等敏感信息)

    一、现象与影响

     项目 | 描述 触发动作 | 修改站点「运行目录」「SSL 证书类型」「伪静态规则」「HTTP 强制 HTTPS」并保存 表现 | 面板右上角 Nginx 状态变为「已停止」,站点列表出现红色「已停止」 影响 | 单机承载全部站点,Nginx 一停即全站不可访问 持续时间 | 数秒到数分钟不等,最终自行恢复或被守护任务拉起 频率 | 每次改站点设置几乎必现

    二、排查过程(由外到内)

    1. 先确认「是不是真的停了」

    对若干站点做轻量 HTTP 探测(只发 HEAD,不扫描):

    curl -s -o NUL -D - --max-time 10 http://<站点域名>/

    响应头出现 Server: nginx 说明 Nginx 实际在运行;此时面板显示「已停止」可能只是状态展示滞后或单站点配置被停用。

    2. 确认服务形态

    sc query nginx sc qc nginx

    本机结果:

    • STATE: 4 RUNNING(WIN32_OWN_PROCESS,本地系统账户,AUTO_START)

    • BINARY_PATH_NAME 指向宝塔自带的服务包装器

    • ERROR_CONTROL: NORMAL(未设置服务失败时的系统级动作)

    3. 关键一步:查是否有失败恢复

    sc qfAIlure nginx

    本机初始结果:

    RESET_PERIOD : 0 FAILURE_ACTIONS : (空)

    即服务没有任何自动恢复配置——一旦停掉,Windows 不会主动拉起,只能等面板自带的服务守护任务,中间就是全站不可用的真空期。

    4. 排除「配置写坏」

    findstr /i /c:"emerg" C:\BtSoft\nginx\logs\error.log

    日志里确实有历史 [emerg],但全部集中在过去的时间段,内容为:

    • 抄了 Linux 配置:unix:/var/run/php/php-fpm.sock(Windows 不支持 unix socket)

    • include snippets/fastcgi-php.conf(Linux 路径不存在)

    • 伪静态里重复 location "/"

    • 日志文件 Access is denied

    关键判断:出问题当天的停站时间点,日志里一条 emerg 都没有 → 不是新配置写坏,而是服务被停掉后没被拉起。

    5. 配置整体校验

    cd /d C:\BtSoft\nginx && nginx.exe -t

    输出:

    nginx: the configuration file ... syntax is ok nginx: configuration file ... test is successful

    仅有 conflicting server name "_" 之类的无害警告 → 当前配置本身合法。

    三、根因

    两个条件叠加:

    1. 改站点设置 = 重写 vhost + 重启 Nginx。Windows 版的重启是「停止服务 → 启动服务」,中间必然有短暂中断。

    2. Nginx 服务没有配置失败恢复动作。只要启动那一步失败(端口未及时释放、进程残留、配置校验未通过),服务就停在 STOPPED,且没有任何机制自动拉起。

    因此每次保存都变成「赌一把启动成功」,失败即全站中断。

    四、修复步骤

    原则:只改服务的恢复策略,不重启服务、不改站点配置。改前先备份现状。

    1. 备份当前恢复策略

    sc qfailure nginx > C:\BtSoft\nginx\failure_backup_<日期>.txt

    2. 写入失败自动重启

    sc failure nginx reset= 86400 actions= restart/5000/restart/5000/restart/5000

    参数含义:

     参数 | 含义 reset= 86400 | 失败计数在 24 小时后重置 restart/5000 ×3 | 失败后延迟 5 秒重启,最多连续 3 次

    3. 复核

    sc qfailure nginx sc query nginx

    期望:

    FAILURE_ACTIONS : 重启动 -- 延迟 = 5000 微秒 ×3 RESET_PERIOD : 86400 STATE : 4 RUNNING

    sc failure 只改配置,不会中断正在运行的服务。

    五、验证结果

     检查项 | 结果 恢复动作 | 3 条「重启动,延迟 5 秒」 服务状态 | 执行前后均为 RUNNING,无业务中断 站点可用性 | 抽查站点均返回 Server: nginx 实际效果 | 后续改设置时状态短暂变为「已停止」,5~10 秒内自动回到「运行中」

    六、这个修复能覆盖什么、不能覆盖什么

    • ✅ 能覆盖:服务崩溃、启动失败(本次问题的主要形态)

    • ❌ 不能覆盖:面板主动「停止服务」这种正常停止(Windows 不认为它是失败),以及配置语法错误导致的启动失败未被计数的情况

    所以它是兜底,不是根治。根治要靠下面这些习惯。

    七、预防措施

    1. 改设置前先校验配置:nginx.exe -t,通过再保存

    2. 改前备份站点配置:把对应 vhost 文件复制一份加了日期的副本

    3. 一次只改一项:保存后确认状态回到「运行中」,再改下一项

    4. 保留面板的「系统服务守护」计划任务:那是第二道保险,不要停用

    5. 运行目录变更前先确认目录真实存在:填了不存在的目录会导致站点 404 甚至加载失败

    6. SSL 优先用自动签发:手填「其他证书」时务必确认证书文件路径非空且存在

    八、完整命令清单(可直接复用)

    :: 1. 现状检查 sc query nginx sc qc nginx sc qfailure nginx
    :: 2. 备份恢复策略
    sc qfailure nginx > C:\BtSoft\nginx\failure_backup_.txt
    
    :: 3. 写入失败自动重启(延迟 5 秒,最多 3 次,24 小时重置计数)
    sc failure nginx reset= 86400 actions= restart/5000/restart/5000/restart/5000
    
    :: 4. 复核
    sc qfailure nginx
    sc query nginx
    
    :: 5. 配置合法性校验
    cd /d C:\BtSoft\nginx && nginx.exe -t
    
    :: 6. 回滚(恢复无失败动作的初始状态)
    sc failure nginx reset= 0 actions= ""

    回滚命令会把恢复策略清空;执行前请确认备份文件仍在。

    九、经验总结

    • 在 Windows 上,「服务在运行」和「服务能自愈」是两件独立的事;AUTO_START 只管开机启动,不管崩溃重启

    • 面板类工具的「重启」在 Windows 上等价于停服务 + 起服务,评估风险时要按「会短暂中断全站」来对待

    • 判断「配置问题」还是「服务生命周期问题」,最有效的一招是对比故障时间点与错误日志时间戳:日志干净而服务停了,就是进程管理问题

    • 宝塔 Windows 面板的 web 终端对多行粘贴不友好,命令要一条一条执行