我有一组从根本上链接的服务(理想情况下它们应该作为单个服务/进程运行,但这项工作仍然需要完成),因为我希望一个服务的故障也导致其他服务重新启动。
我使用目标单元同时启动它们,并将它们全部设置Restart=always
为单独恢复,但如果一项服务因任何原因失败,则不会重新启动其他服务。
我想我可能会逃脱使用该BindsTo
指令,如果单个服务失败(例如进程被终止),该指令似乎会停止所有服务。
我的服务文件目前如下所示:
[Unit]
Description=foo
After=syslog.target network.target
BindsTo=foo.service bar.service baz.service all-services.target
[Service]
User=foo
WorkingDirectory=~
Restart=always
RestartSec=90
StartLimitInterval=400
StartLimitBurst=3
SyslogIdentifier=foo
ExecStart=/path/to/binary
[Install]
WantedBy=all-services.target
分组目标定义为:
[Unit]
Description=all-services
BindsTo=foo.service bar.service baz.service
但该BindsTo
指令似乎会在一个服务出现故障时完全停止所有服务,并且从不尝试重新启动。
我似乎找不到任何表明该服务组重新启动属性可以直接在 systemd 中实现的内容,而不是重新启动依赖链,但我可能会丢失某些内容(或忽略更好的方法)。
答案1
使用PartOf
指示与目标单位一起作为一个整体启动所有服务似乎实现了我的目标。
我的服务文件现在如下所示:
[Unit]
Description=foo
After=syslog.target network.target
PartOf=foo.service bar.service baz.service all-services.target
[Service]
User=foo
WorkingDirectory=~
Restart=always
RestartSec=90
StartLimitInterval=400
StartLimitBurst=3
SyslogIdentifier=foo
ExecStart=/path/to/binary
[Install]
WantedBy=all-services.target
分组目标如下所示:
[Unit]
Description=all-services
PartOf=foo.service bar.service baz.service
我可以通过运行和终止所使用的进程来启动和重新启动服务,从而使foo
它们全部停止并重新启动。bar
baz
systemctl start all-services.target
foo
不清楚的一件事是,如果我运行systemctl stop all-services.target
它将停止所有服务,但从systemctl start all-services.target
停止状态仅启动目标单元而不是所有服务。
我尝试过换成WantedBy
服务RequiredBy
单位,但这似乎没有改变任何东西。
答案2
PartOf
对于您的要求“一个失败将重新启动所有服务”,服务和目标之间的双向就足够了。
服务:
[Unit]
PartOf=all-services.target
[Service]
ExecStart=/path/to/binary
Restart=on-failure
目标:
[Unit]
PartOf=foo.service bar.service baz.service
如果某个单元发生故障并重新启动,目标将向所有服务广播重新启动。
PartOf
服务之间不需要额外的操作。它仅在目标不活跃的情况下才有意义。
这回答给出一个解释,为什么BindsTo
在你的情况下不起作用。
您的
foo
设备正在使用BindsTo=
,这意味着跟踪可能的设备的状态消失。
因此,foo
设备在重新启动之前将变为非活动状态。