Answers:
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 =都没有关系。只要关闭一个并且启动另一个,也没关系关闭两个。在所有情况下,都必须在启动之前下令关机。如果两个单元之间没有排序相关性,则会同时关闭或启动它们,
After=X
“ 如果 X完成,则在X之后执行此操作”,而Require=X
意味着“如果不能执行X ,则根本不执行此操作”。
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
会正常开始。
主要区别之一是,
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
将不会被激活。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 =这样的依赖关系,或者通常一次都拉入并定义一些顺序,因此通常会有一份工作,在这种情况下,它们确实会等待另一个单元的工作。