Windows服务崩溃自动重启需配置sc failure三阶恢复策略,设reset=86400、actions按顺序定义动作与延迟,依赖服务须显式声明;Linux对应Restart=on-failure与RestartSec配合StartLimitBurst避免限频。
Windows 服务崩溃后自动重启的关键配置项
服务崩溃后不自动重启,通常不是因为没设置,而是 recovery 选项只在「服务进程意外退出」时生效,而服务启动失败(如初始化报错、依赖未就绪)或被 net stop/sc stop 主动停止时,该策略完全不触发。
必须通过 sc 命令或服务属性 GUI 显式配置三阶恢复动作,且默认的「重新启动服务」只对第一次崩溃有效,后续需手动设为「运行程序」或「重新启动计算机」才能形成持续响应。
-
sc failure是唯一能完整配置三阶恢复行为的命令,GUI 只暴露前两阶 - 第一阶延迟默认是 60000 毫秒(1 分钟),太短可能和启动竞争,建议设为
60000或更高 - 必须指定
reset= 86400(24 小时),否则计数器不清零,第三阶永远不触发 - 若服务依赖
W32Time或Dhcp等系统服务,需先用sc config <svc> depend= W32Time/<other></other></svc>显式声明,否则启动阶段失败不算「崩溃」
使用 sc failure 配置三阶自动恢复的实操命令
以下命令让服务在崩溃后:1 分钟内重启(第 1 次)、再等 2 分钟重启(第 2 次)、第三次直接运行一个重启脚本,并重置计时器为 24 小时:
sc failure "MyAppService" reset= 86400 actions= restart/60000/restart/120000/run/300000
注意:actions= 后每个动作由斜杠分隔,顺序固定为「动作类型/毫秒延迟」;run 动作需配合脚本路径,但 sc 不校验路径是否存在——如果脚本不存在或无执行权限,第三阶会静默失败。
-
restart行为等价于net start <svc></svc>,不保证服务已完全就绪 -
run动作实际调用的是CreateProcessAsUser,脚本需有交互式桌面权限(默认无),推荐改用计划任务替代 - 修改后必须重启服务本身(
sc stop && sc start)才能使新策略加载,仅 reload 不生效
Linux systemd 服务崩溃自启的等效配置
Linux 下对应机制是 Restart 和 RestartSec,但行为逻辑和 Windows 不同:它对所有退出码生效(包括正常 exit(0)),除非显式排除。
关键点在于 RestartPreventExitStatus 和 StartLimit* 的组合——否则服务反复崩溃会触发速率限制并永久停服。
- 在 service 文件中加:
Restart=on-failure(仅对非 0 退出码重启)或Restart=always(慎用,含 exit(0)) - 必须配
RestartSec=5,否则默认 100ms 内连续重启会被StartLimitIntervalSec拦截 - 若服务启动即崩溃,
systemd默认 10 秒内最多允许 5 次启动尝试,超限后标记为failed并拒绝再启,需设StartLimitIntervalSec=0禁用限制(不推荐)或加大StartLimitBurst=10 -
RestartPreventExitStatus=0可排除正常退出,避免误重启
为什么程序日志里没看到重启记录?
Windows 事件查看器中,服务恢复动作只记录在 System 日志,来源为 Service Control Manager,事件 ID 为 7036(状态变更)和 7009(超时未响应),但 7000(启动失败)和 7040(账户变更)不会触发恢复。Linux 下 journalctl -u <svc> -n 50</svc> 能看到 Started/Starting 循环,但若 RestartSec 太小,日志可能被刷掉。
真正容易被忽略的是:服务主进程 fork 出子进程后自行退出(常见于 Python/Node.js 守护模式),此时 SCM 认为服务已「干净退出」,不视为崩溃,Recovery 完全不触发。必须确保主进程长期存活,或改用 Restart=on-abnormal-exit(systemd)或 ServiceSidType=unrestricted(Windows 服务控制台高级选项)来捕获子进程异常。










