TomOnTime Asked: 2016-11-02 12:04:36 +0800 CST2016-11-02 12:04:36 +0800 CST 2016-11-02 12:04:36 +0800 CST 在 systemd 中,After= 和 Requires= 有什么区别? 772 Requires=我正在创建一个 systemd .service 文件,我需要帮助理解和之间的区别After=。手册页说“配置对其他单元的Requires=需求依赖关系”。和After=“配置单元之间的排序依赖关系”。有什么不同? systemd 3 个回答 Voted Best Answer Sven 2016-11-02T12:25:29+08:002016-11-02T12:25:29+08:00 After=配置服务顺序(仅在 Y 之后执行 X),同时Requires=状态依赖关系。如果您不指定订单,则依赖于另一个的服务将与它所依赖的服务同时启动。此外,我理解它的方式(尽管我现在无法测试并且找不到参考)After=是一种“松散耦合”,如果该After=行中命名的服务是Requires=根本没有开始,如果不满足要求,则会阻止它的开始。 引用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= 都没有关系。两者中的哪一个被关闭也没有关系,只要一个被关闭,另一个被启动。在所有情况下,在启动之前都会下令关闭。如果两个单元之间没有顺序依赖关系,则它们会同时关闭或启动, Sufiyan Ghori 2018-09-18T16:43:54+08:002018-09-18T16:43:54+08:00 主要区别之一是, 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将不会被激活。 Jonathan Kowalski 2019-02-14T07:21:05+08:002019-02-14T07:21:05+08:00 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= 之类的依赖项,或者两者都被同时拉入并定义了一些顺序,通常会有一个工作,在这种情况下,它们会等待另一个单元的工作。
After=
配置服务顺序(仅在 Y 之后执行 X),同时Requires=
状态依赖关系。如果您不指定订单,则依赖于另一个的服务将与它所依赖的服务同时启动。此外,我理解它的方式(尽管我现在无法测试并且找不到参考)After=
是一种“松散耦合”,如果该After=
行中命名的服务是Requires=
根本没有开始,如果不满足要求,则会阻止它的开始。引用https://www.freedesktop.org/software/systemd/man/systemd.unit.html:
和
主要区别之一是,
After
仅检查该单元是否已激活,并且不明确激活指定的单元。Requires
的单元与该单元一起被激活。如果任何所需的单元未能启动,则该单元不会被激活。考虑我有一个单元文件
test-app.service
,这是执行此语句时会发生的情况,
After
检查是否network-online.target
.network-online.target
没有启动,它将等待。test-app
仅在network-online.target
激活后开始如果我有
Requires
,这是执行此语句时会发生的情况,
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= 之类的依赖项,或者两者都被同时拉入并定义了一些顺序,通常会有一个工作,在这种情况下,它们会等待另一个单元的工作。