Systemd定时器用于绑定服务重启,它会重启与其绑定的服务。

3
我是一名有用的助手,可以翻译文本。
我有两个systemd服务ab,其中b是“After”和“BindsTo”ab是一个短命令,每分钟通过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确实停止了,但是当服务b的计时器运行b时,在下一分钟开始时它会重新启动。
systemd文档说明BindsTo声明如果绑定的单元被停止,则此单元也将被停止。

(https://www.freedesktop.org/software/systemd/man/systemd.unit.html#BindsTo=)

我希望通过停止 ab 也会被停止,并且计时器会被禁用。但事实并非如此。你能否帮忙解释一下为什么不仅重启了 b(应该失败),还重启了 a
你能否帮我编辑这些服务,使得:
  • 在启动时,先启动 a,然后再启动 b
  • 当我使用 sudo systemctl stop a 命令时,b 的计时器不会运行
  • 当我使用 sudo systemctl start a 命令时,b 的计时器会重新开始运行
谢谢!
2个回答

1
这里是满足您要求的最简单单位:

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.serviceb.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-a.service完成启动后再启动test-b.timer

关于您观察到的行为:

当您停止a.service时,b.timer仍处于活动状态,并尝试启动b.service以运行其短命令。由于您的b.service指定了BindsTo=a.service,systemd认为b.service还需要启动a.service,并有效地重新启动a.service以使b.service正确运行。

谢谢@duthils - 我也怀疑定时器需要一个BindsTo,但我找不到任何文档表明定时器实际上支持BindsTo。你自己试过了吗?它有效吗?我这周也会花些时间尝试一下。 - Lev Dubinets
我已经尝试过了,计时器在与绑定服务同时启动和停止。就systemd而言,定时器和服务都是单元,[Unit] 部分中的每个设置都适用于任何单元。 - duthils

-1
我可能错了,但我相信"Restart=Always"选项是导致服务a启动并且服务b随后没有停止的原因。
systemd.service的man页面说明,如果将此选项设置为always,
引用: 服务将无论是正常退出、异常终止还是超时都会被重新启动。

https://www.freedesktop.org/software/systemd/man/systemd.service.html#Restart=

所以即使您停止了服务,此选项也会重新启动它。

您可以通过运行以下命令来测试。由于您在一分钟计时器上有“b”服务,因此我会在整点后的10秒运行停止命令(即10:00:10)。然后,我会在20秒后运行状态命令,并查看服务是否已重新启动。

sudo systemctl stop a sudo systemctl status a b


请参阅您链接的文档:作为上述设置的例外,如果使用systemctl stop或等效操作停止服务,则不会重新启动服务。 - Lev Dubinets

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接