systemd 单元文件:依赖项“After=/Before=”不起作用

systemd 单元文件:依赖项“After=/Before=”不起作用

我正在尝试在systemd单元文件中描述的两个服务之间创建依赖关系:

  • a.service 必须在 b.service 之前启动
  • 如果a.service失败则b.service无法启动

这是我所拥有的:

% cat a.service
[Unit]
Description=A-Service
Before=b.service

[Service]
ExecStart=/opt/a.sh

[Install]
WantedBy=multi-user.target

% cat b.service
[Unit]
Description=B-Service
After=a.service

[Service]
ExecStart=/opt/b.sh

[Install]
WantedBy=multi-user.target

这是为服务 A 和 B 执行的简单脚本:

% cat a.sh
#!/bin/sh
echo "A service started"
exit 0

% cat b.sh
#!/bin/sh
echo "B service started"
while [ true ]; do
   sleep 1
do
exit 0

因此,我尝试通过从 返回exit 1来模拟/服务失败a.shsystemctl status a.service将其报告为失败:

Active: failed (Result: exit-code) ...
Process: 843 ExecStart=/opt/a.sh (code=exited, status=1/FAILURE)
...

但是 b.service 仍然启动并处于活动状态:

% systemctl status b.service
...
Active: active (running) ...
Process: 844 ExecStart=/opt/b.sh (code=exited, status=0/SUCCESS)
...

此外,b.service 依赖项确实包含 a.service(状态为“失败”):

% systemctl list-dependencies b.service
...

我究竟做错了什么?是脚本有问题还是[Unit]定义不完整?

答案1

我会用一个Requires第二单元的属性:

如果该单位被激活,列出的单位也将被激活。如果其他单元之一无法激活,并且设置了对失败单元的排序依赖性 After=,则该单元将不会启动。

我还更改了要分叉的每个单元的类型,因为默认类型“简单”将认为该单元在 shell 启动后启动,而分叉单元将等待 shell 退出。此类型更改在此仅对于 A-Service 至关重要。

我还Before=b.service从 A-Service 中删除了,因为从 B 到 A 的向后依赖(使用 B 的“After”指令)对我来说更有意义,而且您不必两者都拥有。

生成的单元文件是:

[Unit]
Description=A-Service

[Service]
Type=forking
ExecStart=/opt/a.sh

[Install]
WantedBy=multi-user.target

和:

[Unit]
Description=B-Service
Requires=a.service
After=a.service

[Service]
Type=forking
ExecStart=/opt/b.sh

[Install]
WantedBy=multi-user.target

相关内容