在systemd中,After =和Requires =有什么区别?


53

我创建一个systemd。服务文件,我需要帮助理解之间的差异Requires=After=。该手册页说,Requires=“配置其他单位需求的依赖。” 和After=“配置单元之间的排序依存关系”。有什么不同?

Answers:


43

After=配置服务顺序(仅在Y之后执行X),同时配置Requires=状态依赖性。如果您不指定订单,则依赖于另一个服务的服务将与它所依赖的服务同时启动。另外,我理解它的方式(尽管我现在无法测试它并且找不到引用)After=是一种“松散耦合”,并且如果该After=行中的名称为根本不会启动,但Require=如果不满足要求,则会阻止启动。

引用https://www.freedesktop.org/software/systemd/man/systemd.unit.html

需要=

配置对其他单元的需求依赖性。如果激活了本机,此处列出的单元也将被激活。如果其他单元之一被停用或激活失败,则该单元将被停用。可以多次指定此选项,也可以在一个选项中指定多个以空格分隔的单位,在这种情况下,将为所有列出的名称创建需求依存关系。请注意,需求依赖关系不会影响服务启动或停止的顺序。必须使用After =或Before =选项独立配置。如果单元foo.service需要使用Requires =配置的单位bar.service,并且没有通过After =或Before =配置的顺序,则如果激活foo.service,则两个单元将同时启动并且彼此之间没有任何延迟。经常,

之前=,之后=

用空格分隔的单元名称列表。配置单元之间的排序依赖性。如果单元foo.service包含设置Before = bar.service并且两个单元都在启动,则bar.service的启动将延迟到foo.service启动为止。请注意,此设置独立于并与由Requires =配置的需求依赖项正交。在After =和Requires =选项中都包含单元名称是一种常见的模式,在这种情况下,列出的单元将在使用这些选项配置的单元之前启动。可以多次指定此选项,在这种情况下,将为所有列出的名称创建排序依存关系。After =是Before =的倒数,即After =确保列出的单元完成启动后启动已配置的单元,而Before =确保相反,即 在启动列出的单元之前,已配置的单元已完全启动。请注意,当两个单元之间的顺序依赖关系被关闭时,将应用启动顺序的倒序。例如,如果一个单元在另一个单元上配置了After =,则如果两个单元都已关闭,则前者将在后者之前停止。给定两个单元之间的顺序依赖性,如果一个单元关闭而另一个单元启动,则在启动之前对关闭进行排序。排序依存关系是After =还是Before =都没有关系。只要关闭一个并且启动另一个,也没关系关闭两个。在所有情况下,都必须在启动之前下令关机。如果两个单元之间没有排序相关性,则会同时关闭或启动它们,


7
如果不是命令说明,则有什么依存关系?(严重...我不明白区别)
TomOnTime

看到我的编辑。我的理解是:After=X如果 X完成,则在X之后执行此操作”,而Require=X意味着“如果不能执行X ,则根本不执行此操作”。
Sven

Before=手册页中的部分似乎证实了这一点。If a unit foo.service contains a setting Before=bar.service and both units are being started, bar.service's start-up is delayed until foo.service is started up 据我了解,如果bar.service不开始执行该命令就不会执行,而是foo.service会正常开始。
斯文

9

主要区别之一是,

  • After 仅检查设备是否已激活,并且不显式激活指定的设备。
  • 列出Requires的单元与该单元一起被激活。如果任何必需的单元无法启动,则不会激活该单元。

考虑我有一个单位文件test-app.service

[Unit]
Description=test app
After=network-online.target

这是执行此语句时将发生的情况,

  • After检查是否network-online.target
  • 如果network-online.target没有开始,它将等待。
  • test-app仅在network-online.target活动后开始

如果我有Requires相反,

[Unit]
Description=test app
Requires=network-online.target

这是执行此语句时将发生的情况,

  • network-online.target并且test-app一起被激活
  • 如果network-online.target启动失败test-app将不会被激活。

2

systemd是工作经理。手册页对工作方式不是很精确。

当您启动时,systemd要做的是建立一个由锚作业组成的事务(即default.target的启动作业)。所有这些依赖项和关系的作用是定义如何以及将触发哪些作业。排序定义了每个其他作业将等待的作业。因此,default.target单元位于这一切的中心,这就是为什么在启用单元时使用反向依赖关系的原因,该反向依赖关系可以通过systemctl enable创建一个文件系统符号链接,该链接表示正向依赖关系systemd(也就是为什么您需要在文件系统符号链接中第一名)。类似的是,当您手动启动某个单元时,该单元是锚点,并通过该单元计算交易。

不会太详细,我将解释Requires =和After =的作用。

当您触发启动作业(显式或通过依赖项:内部没有区别)时,Requires =将导致systemd触发所需单元的启动作业。它还具有在本机停止(注意:已停止,不能自行关闭)或重新启动时触发您的停止作业的属性。这意味着,如果某些依赖项/ systemctl导致其停止/重新启动,则您还将停止/重新启动。但是,如果它自行关闭,您将不会停下来,因为没有工作,而且状态更改是在systemd不参与的情况下发生的。那就是您要使用BindsTo =的地方(类似于设备单元,出于明显的原因,在没有systemd参与的情况下它可以变为非活动状态)。

现在,建议使用After =,因为Requires =本身就是这样做的明智之举:如果启动作业失败,则取消requiree。但是,此取消仅适用于wrt作业,即,如果另一个单元未定义顺序,则systemd会同时触发,并且如果其启动作业在启动作业失败之前完成,则不会被取消(实际上无法取消) 。使用After =意味着其他作业将一直等待,直到所需单元的开始作业完成为止,并且根据结果,如果失败,则单元的等待开始作业会被JOB_DEPENDENCY作业结果取消(为什么使用黄色[DEPEND]在这种情况下启动时)。因此,如果不使用After =,则这种无效效果是不确定的。

这就是为什么如果您不想等待另一个单元的启动,则使用Wants =不使用After =会很好:因为那里没有无效,所以没有竞争。在这种情况下,它仅是同步机制。

此外,您还可以在启动时启用两者,而不需要彼此启用,仅定义顺序,在这种情况下,当两者作为同一事务的一部分被拉出时,它们将被排序(或者如果触发了另一个作业,当它要运行的单元的作业正在运行时,它将首先在事务中等待其完成)。

现在,如果没有工作,则订购对该单元无效。但是,由于使用了Requires =和Wants =这样的依赖关系,或者通常一次都拉入并定义一些顺序,因此通常会有一份工作,在这种情况下,它们确实会等待另一个单元的工作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.