我正在创建一个systemd .service文件,我需要帮助来了解Requires=After=之间的区别。手册页显示Requires=“配置对其他单元的需求依赖项”。和After=“配置单元之间的排序依赖性。”有什么区别?

#1 楼

After=配置服务顺序(仅在Y之后执行X),而Requires=状态相关。如果您不指定订单,则依赖于另一个服务的服务将与它所依赖的服务同时启动。另外,按照我的理解(尽管我现在无法测试,也找不到参考),After=是一种“松散耦合”,并且如果在After=中命​​名的语句仍然可以运行带有这种语句的服务生产线根本没有启动,而如果不满足要求,则Requires=会阻止它启动。
引用https://www.freedesktop.org/software/systemd/man/systemd.unit.html:

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



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


评论


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

– TomToTime
16年11月1日在20:29

看到我的编辑。我的理解:After = X表示“如果X完成,则在X之后执行此操作”,而Require = X表示“如果不能X则完全不执行此操作”。

– Sven
16年11月1日在20:32

手册页的Before =部分似乎可以确认这一点。如果单元foo.service包含设置Before = bar.service并且两个单元都正在启动,则bar.service的启动将延迟到foo.service启动为止。据我所知,如果bar.service仍然无法启动,而foo.service将正常启动。

– Sven
16年11月1日在20:39

#2 楼

主要区别之一是
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.targettest-app
如果network-online.target无法启动test-app将不会被激活。


#3 楼

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 =,这种无效效果是不确定的。

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

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

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