绑定服务的 Systemd 计时器重新启动它绑定的服务
Systemd timer for a bound service restarts the service it is bound to
我有两个系统服务 a
和 b
,其中 b
是 "After" 和 "BindsTo" a
,b
是一个简短的命令,每分钟使用 systemd 计时器启动一次。
这是我的配置:
$ cat /systemd/a.service
[Unit]
After=foo
BindsTo=foo
[Service]
ExecStart=/opt/a/bin/a
Group=lev
User=lev
Restart=Always
WorkingDirectory=/opt/a
$ cat /systemd/b.service
[Unit]
After=a
BindsTo=a
[Service]
ExecStart=/opt/b/bin/b
Group=lev
User=lev
WorkingDirectory=/opt/b
$ cat /systemd/b.timer
[Unit]
[Timer]
OnCalendar=*:0/1:00
当我 运行 sudo systemctl stop a
时,服务 a
确实停止了,但是当服务计时器 [=12] 的下一分钟开始时它又重新启动=] 运行s b
systemd 文档指出 BindsTo
declares that if the unit bound to is stopped, this unit will be stopped too.
(https://www.freedesktop.org/software/systemd/man/systemd.unit.html#BindsTo=)
我希望通过停止 a
,b
也会停止,并且计时器会被禁用。不是这种情况。你能帮忙解释一下为什么 b
计时器不仅会重新启动 b
(应该会失败),还会重新启动 a
吗?
你也能帮我编辑这些服务吗:
- 开机时,先启动a,然后启动b
- 当我
sudo systemctl stop a
时,b
的定时器不运行
- 当我
sudo systemctl start a
时,b
的计时器再次开始 运行ning
提前致谢!
我可能弄错了,但我相信“Restart=Always”选项是名为 a 的服务启动的原因,因此名为 b 的服务随后没有停止的原因。
systemd.service 的手册页说明了此选项是否设置为始终
the service will be restarted regardless of whether it exited cleanly
or not, got terminated abnormally by a signal, or hit a timeout.
https://www.freedesktop.org/software/systemd/man/systemd.service.html#Restart=
因此,即使您正在停止服务,此选项也会重新启动它。
您可以通过运行执行以下命令来测试它。由于您在一分钟计时器上有服务“b”,我会 运行 在一分钟结束后 10 秒停止命令(即 10:00:10)。然后我会在20秒后运行状态命令,看看服务是否已经重启。
sudo systemctl 停止一个
sudo systemctl status a b
以下是满足您的限制的最简单的单位:
test-a.service
[Service]
ExecStart=sleep 3600 # long-running command
test-b.service
[Service]
ExecStart=date # short command
test-b.timer
[Unit]
After=test-a.service
BindsTo=test-a.service # makes test-b.timer stop when test-a.service stops
[Timer]
OnCalendar=* *-*-* *:*:00
[Install]
WantedBy=test-a.service # makes test-b.timer start when test-a.service starts
别忘了
systemctl daemon-reload
systemctl disable test-b.timer
systemctl enable test-b.timer
应用 [Install]
部分中的更改。
解释:
- 你想要的是将
a.service
绑定到 b.timer
,而不是 b.service
b.service
只是一个短命令,systemctl start b.service
只会运行这个命令,不会启动相关的定时器
- 只有
systemctl start b.timer
会启动计时器
WantedBy
告诉 systemd 在 test-a.service
启动时启动 test-b.timer
BindsTo
告诉 test-b.timer
在 test-a.service 停止时停止
-
After
仅确保 test-b.timer
不会与 test-a.service
同时启动:它将强制 systemd 在 test-b.timer
之后启动 test-a.service
已完成启动。
关于您观察到的行为:
- 当您停止
a.service
时,b.timer
仍然处于活动状态并且它尝试从 b.service
开始到 运行 它的短命令。由于您的 b.service
指定了 BindsTo=a.service
,systemd 认为 b.service
也需要 a.service
启动,并且有效地重新启动了 a.service
for b.service
to 运行正确。
我有两个系统服务 a
和 b
,其中 b
是 "After" 和 "BindsTo" a
,b
是一个简短的命令,每分钟使用 systemd 计时器启动一次。
这是我的配置:
$ cat /systemd/a.service
[Unit]
After=foo
BindsTo=foo
[Service]
ExecStart=/opt/a/bin/a
Group=lev
User=lev
Restart=Always
WorkingDirectory=/opt/a
$ cat /systemd/b.service
[Unit]
After=a
BindsTo=a
[Service]
ExecStart=/opt/b/bin/b
Group=lev
User=lev
WorkingDirectory=/opt/b
$ cat /systemd/b.timer
[Unit]
[Timer]
OnCalendar=*:0/1:00
当我 运行 sudo systemctl stop a
时,服务 a
确实停止了,但是当服务计时器 [=12] 的下一分钟开始时它又重新启动=] 运行s b
systemd 文档指出 BindsTo
declares that if the unit bound to is stopped, this unit will be stopped too.
(https://www.freedesktop.org/software/systemd/man/systemd.unit.html#BindsTo=)
我希望通过停止 a
,b
也会停止,并且计时器会被禁用。不是这种情况。你能帮忙解释一下为什么 b
计时器不仅会重新启动 b
(应该会失败),还会重新启动 a
吗?
你也能帮我编辑这些服务吗:
- 开机时,先启动a,然后启动b
- 当我
sudo systemctl stop a
时,b
的定时器不运行 - 当我
sudo systemctl start a
时,b
的计时器再次开始 运行ning
提前致谢!
我可能弄错了,但我相信“Restart=Always”选项是名为 a 的服务启动的原因,因此名为 b 的服务随后没有停止的原因。
systemd.service 的手册页说明了此选项是否设置为始终
the service will be restarted regardless of whether it exited cleanly or not, got terminated abnormally by a signal, or hit a timeout.
https://www.freedesktop.org/software/systemd/man/systemd.service.html#Restart=
因此,即使您正在停止服务,此选项也会重新启动它。
您可以通过运行执行以下命令来测试它。由于您在一分钟计时器上有服务“b”,我会 运行 在一分钟结束后 10 秒停止命令(即 10:00:10)。然后我会在20秒后运行状态命令,看看服务是否已经重启。
sudo systemctl 停止一个 sudo systemctl status a b
以下是满足您的限制的最简单的单位:
test-a.service
[Service]
ExecStart=sleep 3600 # long-running command
test-b.service
[Service]
ExecStart=date # short command
test-b.timer
[Unit]
After=test-a.service
BindsTo=test-a.service # makes test-b.timer stop when test-a.service stops
[Timer]
OnCalendar=* *-*-* *:*:00
[Install]
WantedBy=test-a.service # makes test-b.timer start when test-a.service starts
别忘了
systemctl daemon-reload
systemctl disable test-b.timer
systemctl enable test-b.timer
应用[Install]
部分中的更改。
解释:
- 你想要的是将
a.service
绑定到b.timer
,而不是b.service
b.service
只是一个短命令,systemctl start b.service
只会运行这个命令,不会启动相关的定时器- 只有
systemctl start b.timer
会启动计时器 WantedBy
告诉 systemd 在test-a.service
启动时启动test-b.timer
BindsTo
告诉test-b.timer
在 test-a.service 停止时停止-
After
仅确保test-b.timer
不会与test-a.service
同时启动:它将强制 systemd 在test-b.timer
之后启动test-a.service
已完成启动。
关于您观察到的行为:
- 当您停止
a.service
时,b.timer
仍然处于活动状态并且它尝试从b.service
开始到 运行 它的短命令。由于您的b.service
指定了BindsTo=a.service
,systemd 认为b.service
也需要a.service
启动,并且有效地重新启动了a.service
forb.service
to 运行正确。