如何确保一个 Upstart 作业在其他 Upstart 作业之前启动?

如何确保一个 Upstart 作业在其他 Upstart 作业之前启动?

这是一个常见的 Upstart 问题,但让我用一个具体案例来说明:

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

事实证明,这是相当具有挑战性的,即使试图改变其他服务的依赖关系(无论如何我认为我们不应该这样做,如果可能的话,我不想触碰其他 Upstart 工作)。

有什么建议吗?

答案1

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

例如,Upstart 配置文件/etc/init/centrify.conf可以这样写:

启动于(启动 cron 或启动 autofs 或启动 nis)

将其转换成英语,翻译如下:

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

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

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

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

答案2

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

场景:你希望服务 A总是在 service-b、service-c 和服务-d 之前运行。

解决方案:为服务 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

用简单的英语来说,这意味着:当服务 b、c 或 d 发出要启动的信号时,它们必须等到服务 a 运行后才能启动。服务 a-wait 作业旨在运行到服务 a 启动为止。一旦服务 a-wait 退出,服务 b、c 和 d 就可以继续运行。

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

注意:在这种“开始于...或...或...”的场景中,“实例 $JOB”行非常重要。否则,您实际上只会阻止 B、C 或 D 中先触发的那个。

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

相关内容