注意:我在 Medium 上写了一篇文章,解释了如何创建服务以及如何避免这个特定问题:使用 systemd 创建 Linux 服务。
原问题:
我正在使用 systemd 来保持工作脚本始终运行:
[Unit]
Description=My worker
After=mysqld.service
[Service]
Type=simple
Restart=always
ExecStart=/path/to/script
[Install]
WantedBy=multi-user.target
尽管如果脚本在几分钟后正常退出,则重新启动工作正常,但我注意到,如果它在启动时反复无法执行,systemd
则会放弃尝试启动它:
Jun 14 11:10:31 localhost systemd[1]: test.service: Main process exited, code=exited, status=1/FAILURE
Jun 14 11:10:31 localhost systemd[1]: test.service: Unit entered failed state.
Jun 14 11:10:31 localhost systemd[1]: test.service: Failed with result 'exit-code'.
Jun 14 11:10:31 localhost systemd[1]: test.service: Service hold-off time over, scheduling restart.
Jun 14 11:10:31 localhost systemd[1]: test.service: Start request repeated too quickly.
Jun 14 11:10:31 localhost systemd[1]: Failed to start My worker.
Jun 14 11:10:31 localhost systemd[1]: test.service: Unit entered failed state.
Jun 14 11:10:31 localhost systemd[1]: test.service: Failed with result 'start-limit'.
同样,如果我的工作脚本多次失败且退出状态为255
,systemd
则放弃尝试重新启动它:
Jun 14 11:25:51 localhost systemd[1]: test.service: Failed with result 'exit-code'.
Jun 14 11:25:51 localhost systemd[1]: test.service: Service hold-off time over, scheduling restart.
Jun 14 11:25:51 localhost systemd[1]: test.service: Start request repeated too quickly.
Jun 14 11:25:51 localhost systemd[1]: Failed to start My worker.
Jun 14 11:25:51 localhost systemd[1]: test.service: Unit entered failed state.
Jun 14 11:25:51 localhost systemd[1]: test.service: Failed with result 'start-limit'.
有没有办法systemd
强制总是几秒钟后重试?
答案1
我想稍微扩展一下拉胡尔的回答。
systemd 尝试重新启动多次 ( StartLimitBurst
),如果在 内达到尝试计数,则停止尝试StartLimitIntervalSec
。两个选项都属于该[unit]
部分。
执行之间的默认延迟为 100 毫秒(RestartSec
)这会导致非常快地达到速率限制。
对于具有以下功能的设备,systemd 不会再尝试自动重新启动定义重启策略:
请注意,已配置
Restart=
且达到启动限制的单元将不再尝试重新启动;但是,它们仍然可以在稍后的时间点手动重新启动,从那时起,重新启动逻辑将再次激活。
拉胡尔的回答很有帮助,因为较长的延迟会阻止在时间内到达错误计数器StartLimitIntervalSec
。正确的答案是将RestartSec
和都设置StartLimitBurst
为合理的值。
答案2
是的, 有。您可以在部分下指定x
几秒后重试[Service]
,
[Service]
Type=simple
Restart=always
RestartSec=3
ExecStart=/path/to/script
保存文件后,您需要重新加载守护程序配置以确保systemd
了解新文件,
systemctl daemon-reload
然后重新启动服务以启用更改,
systemctl restart test
正如您所要求的,查看文档,
Restart=on-failure
听起来是一个不错的推荐。
答案3
systemd 放弃尝试重新启动它
不,systemd 放弃尝试重新启动它一会儿。这在您提供的日志中清楚地显示:
6 月 14 日 11:25:51 本地主机 systemd[1]: test.service:失败,结果为“start-limit”。
这是速率限制的开始。
短暂的长度是在服务单元中使用设置指定的StartLimitIntervalSec=
。通过设置指定在该间隔内触发速率限制机制所需的启动次数StartLimitBurst=
。如果您的系统上没有任何与普通 systemd 不同的地方,包括这两个设置的默认值,那么它会在 10 秒内增加 5 次。
StartLimitIntervalSec=0
禁用速率限制,因此 systemd 将永远重试而不是放弃。但是,更好的方法是让您的服务不那么频繁退出,或者在退出和重新启动之间足够空闲以使其不超过速率限制阈值。
请注意,速率限制并不关心您的服务如何退出。它会根据尝试启动/重新启动的次数触发,无论其原因是什么。
进一步阅读
- 伦纳特·珀特林 (2013-10-07)。
systemd.unit
。 systemd 手册页。 freedesktop.org。 - Systemd 的 StartLimitIntervalSec 和 StartLimitBurst 永远不起作用
答案4
如果您的服务在之后没有重新启动,reboot
请确保您之前已启用它:
sudo systemctl enable your.service