在 systemd 单元文件的 `[Service]` 段落中设置 `Restart=on-failure` 或 `Restart=always` 可实现服务进程退出后自动拉起。该配置适用于需要高可用的后台守护进程,需注意配置 `RestartSec` 避免频繁重启循环消耗系统资源。
先说结论:通过修改 unit 文件的 `[Service]` 段配置重启策略,systemd 可在进程退出时自动尝试恢复服务。
- 适合:需要长期运行的后台服务、数据库、Web 服务器
- 先准备:备份原 unit 文件、确认服务退出码含义
- 验收:手动杀死进程后观察 systemd 是否自动重建进程
命令速用版
以下命令用于编辑配置、重载守护进程并验证状态,需在拥有 sudo 权限的终端执行。
sudo systemctl edit `--full` <service_name>
sudo systemctl daemon-reload
sudo systemctl restart <service_name>
systemctl status <service_name>为什么会这样
systemd 作为初始化系统,负责监控主进程 PID 并在退出时根据策略行动。
systemd 管理服务的核心机制是监控主进程(Main PID)的生命周期。当进程退出时,systemd 会捕获退出状态码(Exit Code)。`Restart` 指令告诉 systemd 面对不同退出状态时应采取的动作。如果未配置重启策略,服务进程退出后状态将变为 `inactive` 或 `failed`,不会自动恢复。
分步处理
按以下步骤配置自动重启,每步完成后建议检查配置文件语法。
步骤 1:编辑单元文件
使用 `edit `--full`` 打开完整配置文件,或使用 `edit` 创建覆盖配置。推荐直接编辑原文件以便查看完整上下文。
sudo systemctl edit `--full` <service_name>步骤 2:配置重启策略
在 `[Service]` 段落中添加或修改 `Restart` 和 `RestartSec` 参数。
[Service]
Restart=on-failure
RestartSec=5s`Restart=on-failure` 表示进程非正常退出(退出码非 0 或被信号终止)时重启。`RestartSec=5s` 表示重启前等待 5 秒,避免瞬间频繁重启。
步骤 3:重载配置并启动
修改文件后必须通知 systemd 重新加载配置,然后重启服务使策略生效。
sudo systemctl daemon-reload
sudo systemctl restart <service_name>怎么验证是否生效
通过手动终止进程并观察状态变化来验证自动重启功能。
1. 获取进程 ID
systemctl show <service_name> -p MainPID2. 模拟崩溃
使用 kill 命令强制终止进程,模拟崩溃场景。
sudo kill -9 <MainPID>3. 检查状态
立即查看服务状态,`Active` 字段应显示 `activating` 随后变为 `active`,且 `MainPID` 应发生变化。
systemctl status <service_name>4. 查看日志
确认日志中是否有重启记录。
journalctl -u <service_name> -f常见坑
配置自动重启时需注意退出码定义和重启频率限制,避免陷入重启循环。
- 重启循环保护:systemd 默认有 `StartLimitBurst` 和 `StartLimitIntervalSec` 限制。如果在短时间内重启次数过多,systemd 会停止尝试重启并将服务标记为 failed。公开资料中没有看到可靠的量化数据说明具体阈值对业务的影响,建议根据业务容忍度调整。
- 退出码误解:`Restart=on-failure` 仅在退出码非 0 时触发。如果程序正常退出(码为 0)但业务逻辑异常,systemd 不会重启。此时应考虑 `Restart=always` 或配合 watchdog 机制。
- Type 类型匹配:对于 `Type=forking` 的服务,确保 `PIDFile` 配置正确,否则 systemd 可能无法正确监控主进程,导致重启策略失效。
常见问题
Restart=always 和 on-failure 有什么区别?
always 无论进程如何退出都会重启,on-failure 仅在非零退出码时重启。
`Restart=always` 适用于即使正常退出也需要保持运行的服务(如某些守护脚本)。`Restart=on-failure` 适用于正常退出即表示任务完成无需重启的场景。
如何查看服务重启了多少次?
使用 systemctl show 命令查看 NRestarts 属性。
systemctl show <service_name> -p NRestarts如何临时禁止自动重启?
在命令行启动时覆盖配置参数,或修改单元文件设置 Restart=no。
临时测试可使用 `systemctl start `--set-property`=Restart=no <service_name>`。永久禁止需修改 unit 文件并执行 `daemon-reload`。
参考来源
- freedesktop.org, systemd.service(5) — systemd documentation, https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html