Systemd Restart =总是不被接受


53

注意:我在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总是在几秒钟后重试吗?

Answers:


53

我想扩展一下拉胡尔的答案。

SystemD尝试重新启动多次(StartLimitBurst),如果在内达到尝试次数,则停止尝试StartLimitIntervalSec。这两个选项都属于该[unit]部分。

执行之间的默认延迟为100ms(RestartSec),这会导致非常快地达到速率限制。

对于定义了“ 重启”策略的设备,SystemD不会再尝试进行任何自动重启:

请注意,已配置Restart=且达到启动极限的设备不再尝试重启。但是,它们仍可能在以后手动重新启动,从那时起,重新启动逻辑将再次被激活。

Rahul的回答很有帮助,因为较长的延迟会阻止在StartLimitIntervalSec一段时间内到达错误计数器。正确的答案是同时设置RestartSecStartLimitBurst以合理的值,但。


5
现在,我(终于)了解了它的工作原理,经过反复试验,我可以看到您的答案是最正确的。对我而言,底线是:设置StartLimitIntervalSec=0和遮挡。
本杰明

34

是的,有。您可以x[Service]部分下指定在几秒钟后重试,

[Service]
Type=simple
Restart=always
RestartSec=3
ExecStart=/path/to/script

保存文件后,您需要重新加载守护程序配置以确保systemd知道新文件,

systemctl daemon-reload

然后重新启动服务以启用更改,

systemctl restart test

根据您的要求,查看文档,

Restart=on-failure

听起来像是不错的推荐。


看来确实可行,谢谢!因此,为了更好地理解这一点,在没有RestartSec指令的情况下,systemd尝试多次快速重启,然后进入永久性故障状态;东西不能当发生RestartSec规定的?
本杰明·

另外,我注意到它会延迟我的工作程序的“正常”重启(几分钟后,我有意地优雅地退出了工作程序);有什么办法只能延迟失败的重启?
本杰明

@Benjamin看到我的更新
Rahul

@Benjamin,您可以在此处查看更多参数。
拉胡尔

3
根据doc判断,always是的超集on-failure,因此无济于事!
本杰明·2016年

4

systemd放弃尝试重新启动它

否。systemd放弃了尝试重新启动它的时间。您提供的日志中清楚地显示了这一点:

6月14日11:25:51 localhost systemd [1]:test.service:结果'start-limit'失败

这是速率限制的开始。

使用StartLimitIntervalSec=设置在服务单元中指定一会儿的时间长度。通过StartLimitBurst=设置指定在该时间间隔内触发速率限制机制所需的启动次数。如果您的系统上没有任何与Vanilla Systemd不同的地方,包括这两个设置的默认值,则它是10秒钟内的5倍。

StartLimitIntervalSec=0禁用速率限制。但是,使您的服务要么不经常退出,要么在退出和重新启动之间保持足够的空闲,以使其不超过速率限制阈值,是一种更好的方法。

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

进一步阅读


5
但是,它似乎确实永久放弃了:“活动:自周三2016-06-15 CEST以来失败(结果:开始限制); 12小时前”。它保持这种状态,并且脚本不再执行。我试着手动设置StartLimitIntervalSec=10StartLimitIntervalSec=5,没有运气。
本杰明

4
默认情况下,它确实永久放弃。见github.com/systemd/systemd/issues/2416
亚当·古德

2
底线:设置为停止以防止其永久放弃StartLimitIntervalSec=0
本杰明
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.