![systemd 服务如何在启动时运行直至成功?](https://linux22.com/image/1619749/systemd%20%E6%9C%8D%E5%8A%A1%E5%A6%82%E4%BD%95%E5%9C%A8%E5%90%AF%E5%8A%A8%E6%97%B6%E8%BF%90%E8%A1%8C%E7%9B%B4%E8%87%B3%E6%88%90%E5%8A%9F%EF%BC%9F.png)
我有一个 systemd 服务,可以在启动时升级 linux。服务可以工作,但问题是当 debian 启动时,网络连接已关闭,因此服务显示成功但实际上并没有更新系统。
Tor、systemd-timesyncd 等其他服务将等待网络连接开启。
如何在我的 systemd 服务(如 tor 或 systemd-timesyncd)中执行相同操作。
[Unit]
Description=Upgrade linux system
Requires=network-online.target
After=network-online.target network.target local-fs.target systemd-logind.service
RequiresMountsFor=/var/log /var/run /var/lib /boot
[Service]
ExecStart=/bin/sh -c \
'apt-get update && \
apt-get upgrade -y && \
apt-get dist-upgrade -y && \
apt-get autoremove '
Restart=on-failure
[Install]
WantedBy=multi-user.target
谢谢你!
答案1
不幸的是,network-online.target 的实现不一致,并且不可靠。最好不要依赖它。相反,您可以按照标题要求进行操作...让服务不断重试直到成功。请注意,这是一种黑客行为。
Systemd 具有一项功能,即如果服务在一定时间范围内失败了一定次数,它将停止尝试重新启动服务。无论设置如何,它都会这样做Restart
。解决此问题的唯一方法是结合使用StartLimitIntervalSec
、StartLimitBurst
和RestartSec
设置。
StartLimitIntervalSec 和 StartLimitBurst:
配置单元启动速率限制。在间隔时间内启动次数超过突发次数的单元将不再允许启动。使用 StartLimitIntervalSec= 配置检查间隔(默认为管理器配置文件中的 DefaultStartLimitIntervalSec=,将其设置为 0 以禁用任何类型的速率限制)。使用 StartLimitBurst= 配置允许每个间隔启动的次数(默认为管理器配置文件中的 DefaultStartLimitBurst=)。这些配置选项与服务设置 Restart= 结合使用特别有用(请参阅 systemd.service(5));但是,它们适用于所有类型的启动(包括手动启动),而不仅仅是由 Restart= 逻辑触发的启动。请注意,配置为 Restart= 且达到启动限制的单元将不再尝试重新启动;但是,在间隔过后,它们仍可以在稍后手动重新启动。从此时起,重启逻辑将再次激活。请注意,systemctl reset-failed 将导致服务的重启速率计数器被刷新,如果管理员想要手动启动一个单元,而启动限制会干扰这一点,这将非常有用。请注意,此速率限制是在执行任何单元条件检查后强制执行的,因此,条件失败的单元激活不会计入此速率限制。此设置不适用于切片、目标、设备和范围单元,因为它们是激活可能永不失败或可能仅成功一次的单元类型。
当某个单元由于垃圾收集逻辑而被卸载时(见上文),其速率限制计数器也会被清除。这意味着为不连续引用的单元配置启动速率限制不会产生任何效果。
重启安全:
配置重新启动服务之前的休眠时间(使用 Restart= 配置)。采用无单位的秒值,或时间跨度值,例如“5 分 20 秒”。默认为 100 毫秒。
这个想法是让RestartSec
*StartLimitBurst
大于StartLimitIntervalSec
。对于你的情况,你可以这样做:
[Unit]
Description=Upgrade linux system
Requires=network-online.target
After=network-online.target network.target local-fs.target systemd-logind.service
RequiresMountsFor=/var/log /var/run /var/lib /boot
# If unit restarts more than 5 times in 140 seconds
# do not attempt to restart further
StartLimitIntervalSec=140
StartLimitBurst=5
[Service]
ExecStart=/bin/sh -c \
'apt-get update && \
apt-get upgrade -y && \
apt-get dist-upgrade -y && \
apt-get autoremove '
Restart=on-failure
# attempt to restart (on-failure) after 30 seconds
RestartSec=30
[Install]
WantedBy=multi-user.target
注意:如果启用,此服务将仅在启动时运行一次。要按计划运行此服务,请查看systemd 定时器。