30

我正在运行此答案中描述的多个工作人员实例:自动启动多个新贵实例

问题:我可以一次重新启动所有实例吗?

要开始我的工人,我可以这样做:

initctl 启动我的工人

然后允许我这样做:

initctl status worker N=1 worker (1) 启动/运行,进程 551

initctl status worker N=2 worker (2) 启动/运行,进程 552

有没有办法做这样的事情:

initctl 重启我的工人

我希望能够重新启动所有实例,而不必知道有多少正在运行。

这是我的 my-workers.conf

start on stopped cloud-init
stop on shutdown

env NUM_WORKERS=4

script
  for i in `seq 1 $NUM_WORKERS`
    do
      start worker N=$i
    done
end script

和worker.conf

stop on shutdown

chdir /path/to/current

respawn

instance $N

script
  exec su -c "/home/worker/.rvm/bin/rvm-shell -c 'bundle exec rake work 2>&1 >> /var/log/worker-$N.log'" worker
end script
4

4 回答 4

36

worker.conf你只需要改变这一行:

stop on shutdown

到:

stop on stopping my-workers

my-workers.conf改为使用pre-start,而不是script

pre-start script
  for i in `seq 1 $NUM_WORKERS`
  do
    start worker N=$i
  done
end script

现在my-workers将保持状态:由于工作发生在pre-startmy-workers主进程将不存在,因此不会退出。 stop on stopping my-workers导致工人在停止时my-workers停止。当然,当它再次启动时,它会再次启动工人。

(仅供参考,stop on shutdown什么都不做,因为shutdown它不是系统事件。man upstart-events对于所有定义的事件)所以你也应该将 my-workers 更改为stop on runlevel [06]

于 2012-09-07T17:33:18.547 回答
7

我用上面的例子和 SpamapS 的答案试了一下,我收到了:

init: my-workers pre-start process (22955) terminated with status 127

/var/log/upstart/my-workers.log我发现问题:

/proc/self/fd/9: 6: /proc/self/fd/9: end: not found

中的endfor 循环my-workers.conf似乎是错误的语法。我换了

script
  for i in `seq 1 $NUM_WORKERS`
    do
      start worker N=$i
    done
  end
end script

script
  for i in `seq 1 $NUM_WORKERS`
  do
    start worker N=$i
  done
end script

它奏效了!

于 2012-11-21T14:31:05.600 回答
1

考虑在 worker.conf 中再添加一个事件:

stop on shutdown or workers-stop

然后你可以从命令行调用

sudo initctl emit workers-stop

您可以添加类似的事件来启动工作人员。为了实现重新启动所有工作人员,请创建一个将发出工作人员停止然后工作人员开始事件的任务。

于 2012-12-26T22:30:30.537 回答
1

本质上,您需要有一个流程来为您的所有组合执行stop许多命令startN=1N=2

一个简单的方法是在一个节中使用几个 bashfor循环。exec script但是,如果进程需要一些时间才能停止(例如,因为它们正在处理某事并且在SIGTERM处理完当前工作后他们正在接受),那么这是低效的,因为您必须等待一个停止才能将信号发送到下一个。

因此,我构建了一个 Upstart 脚本,在https://github.com/elifesciences/builder-base-formula/blob/master/elife/config/etc-init-multiple-processes-parallel.conf上并行停止它们

该脚本由 Salt 编译,使用进程名称与进程名称的映射作为输入。这是一个示例结果:

description "(Re)starts all instances, in parallel"
# http://upstart.ubuntu.com/cookbook/#start-on
start on (local-filesystems and net-device-up IFACE!=lo)
task
script
    timeout=300
    echo "--------"

    echo "Current status of 5 elife-bot-worker processes"
    echo "Now is" $(date -Iseconds)
    for i in `seq 1 5`
    do
        status elife-bot-worker ID=$i || true
    done
    echo "Stopping asynchronously 5 elife-bot-worker processes"
    echo "Now is" $(date -Iseconds)
    for i in `seq 1 5`
    do
        (stop elife-bot-worker ID=$i &) || true
    done

    for i in `seq 1 5`
    do
        echo "Waiting for elife-bot-worker $i to stop"
        echo "Now is" $(date -Iseconds)
        counter=0
        while true
        do
            if [ "$counter" -gt "$timeout" ]
            then
                echo "It shouldn't take more than $timeout seconds to kill all the elife-bot-worker processes"
                exit 1
            fi
            status elife-bot-worker ID=$i 2>&1 | grep "Unknown instance" && break
            sleep 1
            counter=$((counter + 1))
        done
    done
    echo "Stopped all elife-bot-worker processes"

    echo "Starting 5 elife-bot-worker processes"
    for i in `seq 1 5`
    do
        start elife-bot-worker ID=$i
    done
    echo "Started 5 elife-bot-worker processes"

end script
于 2017-01-09T09:14:15.320 回答