Systemd Restart=always 不被遵守

Systemd Restart=always 不被遵守

注意:我在 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'.

同样,如果我的工作脚本多次失败且退出状态为255systemd则放弃尝试重新启动它:

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 将永远重试而不是放弃。但是,更好的方法是让您的服务不那么频繁退出,或者在退出和重新启动之间足够空闲以使其不超过速率限制阈值。

请注意,速率限制并不关心您的服务如何退出。它会根据尝试启动/重新启动的次数触发,无论其原因是什么。

进一步阅读

答案4

如果您的服务在之后没有重新启动,reboot请确保您之前已启用它:

sudo systemctl enable your.service

相关内容