当一个服务启动时 Systemd 停止另一个服务

当一个服务启动时 Systemd 停止另一个服务

例如,我有一些通常相互冲突的服务(相同的端口等)。但我从来不需要它们同时运行。例如,如果我启动 service a,它会检查b或是否c正在运行并停止它们?如果其他服务未运行,则它会b正常启动。但如果是的话,它会stop向其他服务发送命令。

作为现在的解决方法,我只有一个 .sh 运行systemctl stop a.service一个 while 循环,grepssystemctl status a.service直到它返回停止,然后运行systemctl stop c.service一个 while 循环,grepssystemctl status c.service直到它返回停止。两者返回停止后,然后运行systemctl start b.service。然后我制作了相同的文件,但用于启动a.servicec.service,但在我看来,这个解决方法相当混乱,我想知道是否有官方的东西。

答案1

systemd.unit(5):

冲突=

以空格分隔的单位名称列表。配置负面需求依赖性。如果一个单元在另一个单元上有 Conflicts= 设置,则启动前者将停止后者,反之亦然。

请注意,此设置并不意味着排序依赖关系,类似于上面描述的 Wants= 和 Requires= 依赖关系。这意味着,为了确保冲突单元在另一个单元启动之前停止,必须声明 After= 或 Before= 依赖项。使用两个排序依赖项中的哪一个并不重要,因为停止作业始终在启动作业之前排序,请参阅下面 Before=/After= 中的讨论。

如果与单元 B 冲突的单元 A 计划与单元 B 同时启动,则事务要么失败(如果两者都是事务的必需部分),要么被修改以进行修复(如果一个或两个作业都不是事务的必需部分)。在后一种情况下,不需要的作业将被删除,或者如果两者都不是必需的,则将启动冲突的单元并停止冲突的单元。

因此,如果您想杀死B并且C无论何时开始A,只需将其添加[Unit]A.service

[Unit]
Conflicts=B.service C.service

如果您将所有三个单元Conflict=相互组合,那么您将选择要运行的一个。因此,启动 A 将杀死 B&C,启动 B 将杀死 A&C,启动 C 将杀死 A&B。

听起来你想B.service默认运行,所以只有一个应该有WantedBy=multi-user.target关系。不要将其添加到其他项(或不启用它们),否则它们都会尝试在启动时启动,并且它们要么全部失败,要么随机一个将继续运行。

听起来您也想B.service在停止A.service或时开始C.service。尝试更多地考虑你想要什么,而不是你不想要什么。 Systemd 不存在在一个单元关闭时启动另一个单元的关系。要关闭整个系统,systemd 会引发shutdown.target它与一切发生冲突,使它们崩溃。想象一下,如果C停止关机,在关机过程中启动B。

相关内容