我有一个Upstart任务,可以启动基于Starting multiple upstart instances automaticallyRestarting Upstart instance processes的服务的多个实例。它正在工作,并且启动了所有实例,但是在成功启动它们之后,它只是挂起了。如果我将Ctrl-C退出,然后使用service status或在ps中查看实例,则它们都已成功启动,因此挂起时我不知道它在做什么。

这是我的脚本:

description "all-my-workers"

start on runlevel [2345]

task

console log

env NUM_INSTANCES=1
env STARTING_PORT=42002

pre-start script
  for i in `seq 1 $NUM_INSTANCES`;
  do
    start my-worker N=$i PORT=$(($STARTING_PORT + $i))
  done
end script

当我执行service start all-my-workers时,我得到了:
vagrant@vagrant-service:/etc/init$ sudo service all-my-workers start

然后它只是卡在那儿,不再提示我。正如我说的,我可以Ctrl-C出来,看看正在运行的 worker :
vagrant@vagrant-service:/etc/init$ sudo service all-my-workers status
all-my-workers start/running
vagrant@vagrant-service:/etc/init$ sudo service my-worker status N=1
my-worker (1) start/running, process 21938

并在ps中:
worker    21938  0.0  0.1   4392   612 ?        Ss   21:46   0:00 /bin/sh -e /proc/self/fd/9
worker    21941  0.2  7.3 174076 27616 ?        Sl   21:46   0:00 python /var/lib/my-system/script/start_worker.py

我不认为问题出在my-worker.conf中,但以防万一:
description "my-worker"

stop on stopping all-my-workers

setuid worker
setgid worker

respawn

instance $N

console log

env SCRIPT_PATH="/var/lib/my-system/script/"

script
    export PROVIDER=vagrant
    export REGION=all
    export ENVIRONMENT=cert

    . /var/lib/my-system/.virtualenvs/my-system/bin/activate

    python $SCRIPT_PATH/start_worker.py

    END
end script

谢谢一堆!

最佳答案

我如何解决它?

我将假设my-worker是一个长期存在的过程,并且您希望有一种简单的方法来启动和拆除my-worker的多个并行实例。

在这种情况下,您可能不希望all-my-workerstask。您需要以下内容:

description "all-my-workers"

start on runlevel [2345]

console log

env NUM_INSTANCES=1
env STARTING_PORT=42002

pre-start script
    for i in `seq 1 $NUM_INSTANCES`;
    do
        start my-worker N=$i PORT=$(($STARTING_PORT + $i))
    done
end script

pre-stop script
    for i in `seq 1 $NUM_INSTANCES`;
    do
        stop my-worker N=$i PORT=$(($STARTING_PORT + $i)) || true
    done
end script

然后,您可以运行start all-my-workers来启动所有my-worker实例,然后运行stop all-my-workers来停止它们。实际上,all-my-workers成为父作业,用于管理子作业的启动和停止。

为什么?

您列举了两个SO答案,这些答案表明了由父级职位管理子级职位的想法。他们展示:
  • 一个带有script
  • 的任务
  • 带有pre-start
  • 的作业

    您的父项工作是带有pre-start节的任务,因此这就是您遇到这种奇怪行为的原因。

    脚本与预启动

    在引用this Ask Ubuntu answerthis deprecated documentation中,有两个非常重要的语句(重点强调):



    总之,Upstart会忽略(即不受监视)由pre-start节产生的任何后台进程。相反,您必须使用execscript生成Upstart将监视的进程。

    如果省略exec/script节会怎样? Upstart 将坐下来,等待产生一个进程。因此,您可能还编写了while-true循环:
    script
        while true; do
            true
        done
    end script
    

    唯一的区别是,while-true循环是事件锁,而空节会导致死锁。

    工作与任务

    知道了以上内容后,the Upstart documentation for tasks最终使我们了解发生了什么:



    (如果您阅读了有关starting and stopping jobs的文档,那么有关事件和状态的某些细节将更加有意义)。

    用simpiler的术语来说:
  • 在正常的Upstart作业下,由于exec/script节启动了一个长期存在的进程,因此它可能会无限期地阻塞。因此,Upstart一旦完成pre-start节就停止阻止。
  • 使用task,预计exec/script节将在“有限的”时间内阻塞,因为它启动了一个短暂的过程。因此,Ubstart会阻塞直到,exec/script节完成之后的为止。

  • 但是,如果没有exec/script节,会发生什么? Upstart 坐下来,无限期地等待着发布,但是那永远不会发生。
  • job的情况下,这很好,因为在等待进程生成时Upstart不会阻塞,并且调用stop显然足以使其停止等待。
  • 如果是task,Upstart会一直坐着并永远挂着-或直到您中断它为止。但是,由于它仍未找到生成的进程,因此它在技术上仍在运行。这就是为什么您可以在中断后查询状态并查看all-my-workers start/running的原因。

  • 为了利益

    如果出于某种原因,您真的想将父级工作变成一个任务,则实际上需要两个任务:一个启动my-worker实例,另一个停止它们。您还需要从stop on stopping all-my-workers中删除my-worker节。

    我的所有 worker :
    description "starts all-my-workers"
    
    start on runlevel [2345]
    
    task
    
    console log
    
    env NUM_INSTANCES=1
    env STARTING_PORT=42002
    
    script
        for i in `seq 1 $NUM_INSTANCES`;
        do
            start my-worker N=$i PORT=$(($STARTING_PORT + $i))
        done
    end script
    

    停止所有工作人员:
    description "stops all-my-workers"
    
    start on runlevel [!2345]
    
    task
    
    console log
    
    env NUM_INSTANCES=1
    env STARTING_PORT=42002
    
    script
        for i in `seq 1 $NUM_INSTANCES`;
        do
            stop my-worker N=$i PORT=$(($STARTING_PORT + $i)) || true
        done
    end script
    

    关于linux - Upstart任务成功完成后挂起,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28119333/

    10-12 02:02