如何确保一项 Upstart 工作在其他 Upstart 工作之前开始?

Mar*_*ell 33 boot upstart init

这是一个普通的 Upstart 问题,但让我使用一个特定的案例:

Centrify 是一个 NIS 到 ActiveDirectory 的网关。它需要在任何依赖于它提供的身份验证服务的服务之前加载,例如 autofs、cron、nis 等。

事实证明,即使尝试更改其他服务的依赖关系,这也很难实现(我认为无论如何我们都不应该这样做,如果可能的话,我不想触及其他 Upstart 工作) .

建议?

小智 29

解决方案是从另一个方向解决问题:为了满足 Centrify 的启动条件,不必让现有服务依赖于新的 Centrify 服务,而是让新的 Centrify 服务依赖于现有服务。

例如,一个 Upstart 配置文件/etc/init/centrify.conf可以说:

开始(启动 cron 或启动 autofs 或启动 nis)

将其转换为英语,这将翻译为:

cron、autofs 或 nis 启动(以先启动者为准)之前启动 Centrify 服务。

cron、autofs 或 nis 启动的顺序无关紧要:Upstart 将确保 Centrify 将在哪个服务先启动之前启动,从而确保 Centrify 在这些服务中的任何一个启动之前运行。

还要注意,Upstart 会阻止第一个想要启动的服务的启动,直到 Centrify 开始运行。

一旦你习惯了这种方式思考,就非常优雅和简单。

  • 这对我来说似乎完全倒退。当其他事情依赖于 *it* 时,为什么要修改一项服务的 conf 脚本? (4认同)
  • @benw 这样您就不必修改您不拥有的服务的现有设置。 (3认同)
  • @benw 为什么不能在新脚本中使用`start on (started nginx)`? (2认同)
  • @Paccc 不是真的。`start on (started nginx)` 的意思是“在 nginx 之后启动我的服务”。这与“在我的服务之前启动 nginx 因为它需要它”不同。 (2认同)

Mar*_*ell 12

James 的回答适用于 1 对 1 的依赖关系。对于一对多,即确保服务 A 在服务 B、C 和 D 之前启动,您需要采取另一种方法。您可以查看当前的端口映射脚本以供参考,但这里是通用方法:创建等待脚本。

场景:您希望服务 A始终在 service-b、service-c 和 service-d 之前运行。

解决方案:为Service A创建一个等待脚本,命名为“/etc/init/service-a-wait.conf”

# service-a-wait

start on (starting service-b 
    or starting service-c
    or starting service-d)
stop on (started service-a or stopped service-a)

# We know that we have more than one job that needs to wait for service-a and
# will make use of this service, so we need to instantiate.
instance $JOB

# Needed to make starting the job successful despite being killed
normal exit 2
task

script

    status service-a | grep -q "start/running" && exit 0
    start service-a || true

    # Waiting forever is ok.. upstart will kill this job when
    # the service-a we tried to start above either starts or stops
    while sleep 3600 ; do :; done

end script
Run Code Online (Sandbox Code Playgroud)

通俗地说,这意味着:当服务 b、c 或 d 表示要启动时,它们必须等待启动,直到服务 a 运行。service-a-wait 作业旨在运行直到 service-a 启动。一旦 service-a-wait 退出,现在服务 b、c 和 d 可以自由地继续运行。

这将确保 service-a 在其任何反向依赖项尝试启动之前启动并运行。

注意:“instance $JOB”行在这个“开始于...或...或...”场景中很重要。否则,您只会真正阻止 B、C 或 D 中的任何一个先触发。

(老实说,实例化值得更好的解释。现在,就去做吧。;)

  • 我不明白……是什么阻止了启动服务 A 和服务 B 继续启动之间的竞争条件?我不明白 upstart 怎么会知道脚本已经完成了“启动服务-a”……(这可能归咎于 Upstart 的劣质文档……) (3认同)