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

wes*_*wes 41 linux service systemd

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

Ale*_*bes 63

这可能不是在提出问题时出现的,但现在有一个叫做的选项RuntimeMaxSec,它在服务运行一段时间后终止服务.

例如

[Service]
Restart=always
RuntimeMaxSec=604800
Run Code Online (Sandbox Code Playgroud)

对我而言,这似乎比滥用Type=notify和优雅更优雅WatchdogSec.

  • 这仅适用于systemd v> = 229.运行`systemctl --version`查看您的版本 (7认同)
  • 还可以在时间字段中使用单位:`RuntimeMaxSec=7d` (4认同)

Sat*_*urn 33

是的,您可以通过提供服务使您的服务定期重新启动Type=notify.在服务文件的[Service]部分中添加此选项Restart=always以及给予WatchdogSec=xx,其中xx是您想要重新启动服务的时间段.在此处,您的进程将在xx时间段后被systemd杀死,并将再次由systemd重新启动.例如.

[Unit]
.
.

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

[Install]
WantedBy= ....
Run Code Online (Sandbox Code Playgroud)

  • "WatchdogSec"的问题在于它每次重启时都会发送一个SIGABRT(导致核心转储).除了不干净地终止进程外,它还可以最终用coredump填充你的根磁盘. (14认同)
  • 从 ver240 开始,有 WatchdogSignal,因此您可以覆盖 SIGABRT https://github.com/systemd/systemd/blob/master/NEWS (6认同)
  • 聪明!FWIW`type = notify`对于我的愚蠢遗留服务来说不是必需的.但是,使用`Type = simple`设置`WatchdogSec`的工作方式相同. (4认同)
  • @wes 谢谢,`Type=notify` 没有为我启动服务,`Type=`simple` 效果很好(实际上没有任何 `Type` 也可以正常工作,可能 simple 是默认的 `Type` ) (2认同)

mat*_*mat 32

我看到这里的解决方案似乎很优雅,如果有点迂回.关键的想法是创建一个由重启另一个服务的计时器触发的一次性服务.

对于计时器:

[Unit]
Description=Do something daily

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target
Run Code Online (Sandbox Code Playgroud)

对于一次性服务:

[Unit]
Description=Restart service

[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl try-restart my_program.service
Run Code Online (Sandbox Code Playgroud)

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

[Unit]
Description=Restart service

[Service]
Type=oneshot
ExecStart=/bin/systemctl try-restart my_program.service
Run Code Online (Sandbox Code Playgroud)

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

  • 我对日常计时器如何调用一次性服务感到困惑? (3认同)
  • @svandragt这正是它的工作原理.systemd计时器必须与它启动的服务具有相同的名称. (3认同)
  • 为什么这个计时器有“Persistent=true”?如果这里的目的是重新启动服务,并且由于服务器离线而导致计时器没有运行,那么无论如何都会重新启动服务。 (3认同)
  • 我不确定这是不是你要问的,但是,据我所知,一次性服务有一个与之相关的计时器,这个一次性服务的工作就是重启另一个服务.我相信这是通过简单地命名服务及其相关名称的计时器来实现的,即`weeklyRestart.service`和`weeklyRestart.timer`.当我解决这个问题时,我经历了一段链接.给我发消息,我可以发送链接转储. (2认同)
  • @MichaelAmbrose 不一定,您还可以使用`Unit=` 指定另一个服务。 (2认同)

Fri*_*ker 13

怎么样的crontab喜欢

30 3 * * sun /bin/systemctl restart yourService
Run Code Online (Sandbox Code Playgroud)

这将在每个星期天凌晨3:30重新启动服务.

  • @louis-loudog-trottier 这将启动已停止或禁用的服务。如果您只想让它申请正在运行的服务,可以使用“try-restart”命令。参见 https://www.man7.org/linux/man-pages/man1/systemctl.1.html (4认同)

Dan*_*scu 5

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

  • 如果您可以控制服务实现,则可以让它在一段时间后自动结束,例如,在一定次数的迭代后直接退出(如果适用),或者使用带有处理程序的超时计时器,向自身发送 SIGTERM/SIGKILL
  • 如果自愿服务结束不可行/不切实际,您可以使用一个基于 cron 的小型脚本来终止服务进程。


小智 5

想发表评论

[Service]
Restart=always
RuntimeMaxSec=604800
Run Code Online (Sandbox Code Playgroud)

回答上面,但不能没有更多的积分。

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

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

  • 根据 [doc](https://www.freedesktop.org/software/systemd/man/systemd.unit.html):使用 Restart= 的服务单元仅在达到启动限制后才进入失败状态。 (2认同)