如何配置 systemd 服务以定期重启?

How can I configure a systemd service to restart periodically?

我有一个简单的 systemd 服务,需要定期重新启动以防止其进程出错。 systemd 服务是否有定期重启它们的配置选项?所有 Restart* options 似乎都与退出时重新启动服务有关。

只是最终达到相同目标的一些替代方法:

  • 如果您可以控制服务实现,您可以让它在一段时间后自动结束,例如,在一定次数的迭代后简单退出(如果适用)或使用超时计时器和处理程序本身发送 SIGTERM/SIGKILL
  • 如果志愿服务结束不是 feasible/practical,您可以使用一个基于 cron 的小脚本来终止服务进程。

是的,您可以通过 Type=notify 的服务让您的服务定期重启。 在服务文件的 [Service] 部分添加此选项以及 Restart=always 并给出 WatchdogSec=xx,其中 xx 是您要重新启动服务的时间段(以秒为单位)。在这里,您的进程将在 xx 时间段后被 systemd 杀死,并将再次由 systemd 重新启动。 例如

[Unit]
.
.

[Service]
Type=notify
.
.
WatchdogSec=10
Restart=always
.
.

[Install]
WantedBy= ....

我看到了一个解决方案 here,虽然有点迂回,但看起来很优雅。关键思想是创建一个由重新启动 另一个 服务的计时器触发的一次性服务。

对于计时器:

[Unit]
Description=Do something daily

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

对于一次性服务:

[Unit]
Description=Restart service

[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl try-restart my_program.service

对于 Ubuntu 16.04 LTS 上的一次性服务:

[Unit]
Description=Restart service

[Service]
Type=oneshot
ExecStart=/bin/systemctl try-restart my_program.service

此解决方案让您可以利用 systemd 的计时器,包括在一天中的特定时间重新启动服务的能力,而不仅仅是在经过一段时间后。

crontab 怎么样。示例:

30 3 * * sun /bin/systemctl restart yourService

这将在每个星期日的 3:30 上午重新启动名为 yourService 的服务。

如果您想在任何 Unix-like 服务器上工作(例如,您不想担心特定的 systemd 版本等),您可能会喜欢这个解决方案。

对于 systemd 版本 >= 229,有一个名为 RuntimeMaxSec 的选项,它会在 运行 指定时间后终止服务。

例如

[Service]
Restart=always
RuntimeMaxSec=604800

对我来说,这似乎比滥用 Type=notifyWatchdogSec 更优雅。

systemd 提供了一种在供应商提供的 systemd 单元文件中添加和覆盖指令的简洁方法。 man systemd.unit 中描述了插入式单元。例如,如果你想定期重启包提供的 foo 服务,你可以创建一个名为 /etc/systemd/system/foo.service.d/periodic-restart.conf 的文件。内容将如上所示。那么:

 systemctl daemon-reload
 systemctl restart foo

您可以确认 Drop-In 单元已加载,因为它会在状态输出中报告:

 systemctl status

最后,您可以通过搜索 systemctl show 输出来确认指令已被包含:

 systemctl show foo.service | grep RuntimeMax

systemctl show 报告的指令将是“RuntimeMaxUSec`

想对

发表评论
[Service]
Restart=always
RuntimeMaxSec=604800

上面的答案,但不能再 w/o 分了。

评论是此解决方案将调用 OnFailure=failure_handling.service 设置的故障处理。由于计划的重新启动不是真正的故障,因此来自故障处理服务的任何日志记录、通知等都是不需要的,并且可能会造成破坏。

实际的定期重启对于 systemd 来说是一个明智的功能,但我不会屏住呼吸。

Copy-paste systemd版本 >= 229的解决方案:

SERVICE="systemd-resolved.service"
env SYSTEMD_EDITOR=tee sudo -E systemctl edit --system ${SERVICE} <<EOF
[Service]
Restart=always
RuntimeMaxSec=7200
EOF

sudo systemctl daemon-reload && sudo systemctl restart "${SERVICE}"

检查:

systemd-delta | grep ${SERVICE}
# NOTE: property here must be requested with "U": RuntimeMaxUSec
systemctl show ${SERVICE} --property=RuntimeMaxUSec

回滚:

SERVICE="systemd-resolved.service"
sudo rm -r "/etc/systemd/system/${SERVICE}.d"
sudo systemctl daemon-reload
sudo systemctl restart ${SERVICE}

更优雅的是:

SERVICE="systemd-resolved.service"
sudo systemctl set-property ${SERVICE} RuntimeMaxSec=7200

但由于某些原因它不起作用:

Failed to set unit properties on systemd-resolved.service: Cannot set property RuntimeMaxUSec, or unknown property.