Restart 策略是什么
systemd 用 Restart= 决定服务退出后是否自动拉起,用 RestartSec= 决定两次尝试之间的等待时间,这是「自愈」的最小实现:进程崩溃、被 OOM 杀死、异常退出码都可以配置成自动重启。但只有重启策略还不够,启动就失败的服务会被反复拉起,所以要用 StartLimitIntervalSec 与 StartLimitBurst 限制时间窗内的启动次数,超限后单元进入 failed 状态并停止尝试,避免刷爆日志、拖高负载。生产环境要把这两组参数成对写。
基本信息
| 适用平台 | Linux(systemd) |
|---|---|
| 关键参数 | Restart=、RestartSec=、StartLimitIntervalSec=、StartLimitBurst=、TimeoutStopSec= |
| 参数所在段落 | Restart 相关写在 [Service],StartLimit 相关写在 [Unit] |
| 取值差异 | on-failure 对退出码 0 不重启;always 任何退出都重启;on-abnormal 只对被信号杀死或超时重启 |
| 观察手段 | systemctl show -p NRestarts,Restart,RestartUSec,journalctl 里的 Scheduled restart 记录 |
典型使用场景
- 常驻服务崩溃后自动恢复,减少人工介入
- 依赖外部组件(数据库、消息队列)暂不可用时自动重试
- 滚动发布期间让异常退出的实例自行拉起
- 排查「服务为什么反复重启」的起点,用 NRestarts 确认是否形成循环
- 与 Type=notify 配合,用 WatchdogSec= 检测服务假死
策略示例
策略示例
[Unit]
# 时间窗内最多启动 5 次,超过则进入 failed 停止尝试
StartLimitIntervalSec=60
StartLimitBurst=5
[Service]
Restart=on-failure
RestartSec=5
TimeoutStopSec=30
# 数据库类依赖先就绪再拉起
After=network-online.target观察与验证
观察与验证
systemctl show myapp -p NRestarts,Restart,RestartUSec
journalctl -u myapp | grep -i 'Scheduled restart' | tail
systemctl status myapp --no-pager | head -n 8 # 看 Active 与重启计数
systemctl reset-failed myapp # 达到 StartLimit 后重置再试Restart 取值对照
| 取值 | 何时重启 | 适用场景 |
|---|---|---|
| no | 从不重启(默认) | 一次性任务或由外部编排管理生命周期的服务 |
| on-failure | 非 0 退出码、被信号杀死、超时 | 多数常驻服务 |
| always | 任何退出方式,包括正常退出码 0 | 必须持续存在的守护进程 |
| on-abnormal | 被信号杀死或超时,不含正常的非 0 退出 | 希望区分业务主动退出码的服务 |
参数写错段落是最隐蔽的配置错误:Restart= 放进 [Unit]、StartLimit* 放进 [Service] 都不会报错,但也不会生效,单元文件看起来完整却行为异常。
Restart=always 与「启动即失败」的服务组合会形成快速重启循环,几秒内刷出成百上千条日志并推高负载,必须同时设置 StartLimit 与足够长的 RestartSec 退避。