使用分配的计时器限制重新启动 systemd 服务

Restrict restarting systemd service with timer assigned

我有一个分配了 OnCalendar 定时器的 systemd 服务单元。该服务调用运行代码的 JVM,只能按特定计划启动。

这个 systemd 单元(和其他几个)由使用 openstack/ansible-role-systemd_service 角色的 ansible 剧本管理。每次我对它们的单元文件进行一些更改时,它都会重新启动 systemd 服务。

此外,还有一个处理程序,每次 Gitlab CI 管道运行此 ansible 剧本并将新的 .jar 工件上传到服务器时,它都会重新启动所有服务。

是否有任何 systemd 内置机制来限制使用分配给它的计时器重新启动服务?不过,我必须能够 stop/start 手动 stop/start 这些服务需要它。

似乎我可以分叉那个 ansible 角色并添加一些检查,但我想知道一些本机和更直接的方法来实现这一点。

看来我找到方法了:

创建 并且不启用 .service 单元,它将包含下一个:

[Unit]
After = network-online.target
...

[Service]
Type = simple
...
SuccessExitStatus = 143
RestartForceExitStatus = 143
Restart = on-failure
RemainAfterExit = False
StandardOutput = null
StandardError = syslog

[̶I̶n̶s̶t̶a̶l̶l̶]
W̶a̶n̶t̶e̶d̶B̶y̶ ̶=̶ ̶m̶u̶l̶t̶i̶-̶u̶s̶e̶r̶.̶t̶a̶r̶g̶e̶t̶

创建启用 .timer 单元,将包含下一个:

[Timer]
O̶n̶B̶o̶o̶t̶S̶e̶c̶ ̶=̶ ̶0̶m̶i̶n̶
OnCalendar = *-*-* 18:00:00
Persistent = yes

[Install]
WantedBy=multi-user.target

一点解释:

After = network-online.target

需要确保服务只有在联机后才能启动。

Restart = on-failure
SuccessExitStatus = 143
RestartForceExitStatus = 143

需要能够 kill 主进程并使 systemd 重新启动服务,或停止服务 w/o systemd 标记它 failed。这是因为JVM在主进程收到SIGTERM并正常停止时返回143退出代码。

RemainAfterExit = False  

需要 .timer 了解 .service 停止。无论哪种方式,.timer 都会挂在 running 状态,下次不会 运行 服务。

StandardOutput = null
StandardError = syslog

需要阻止主进程将其 INFO 日志写入系统日志,并且只写入错误。

[̶I̶n̶s̶t̶a̶l̶l̶]
W̶a̶n̶t̶e̶d̶B̶y̶ ̶=̶ ̶m̶u̶l̶t̶i̶-̶u̶s̶e̶r̶.̶t̶a̶r̶g̶e̶t̶

省略,因为必须禁用该服务。无论哪种方式,它都会在系统启动时启动。

Persistent = yes

如果错过了目标时间,则需要能够在系统启动后的当天晚些时候启动服务。

O̶n̶B̶o̶o̶t̶S̶e̶c̶ ̶=̶ ̶0̶m̶i̶n̶

省略原因OnCalendar被使用。

所有这些更改似乎都奏效了。