重启Upstart实例进程

30

我正在按照这个答案描述的方式运行多个worker实例:Starting multiple upstart instances automatically

问题: 我能否同时重新启动所有实例?

要启动我的workers,我可以执行以下命令:

initctl start my-workers

然后可以执行:

initctl status worker N=1 worker (1) start/running, process 551

initctl status worker N=2 worker (2) start/running, process 552

有没有像这样的方法:

initctl restart my-workers

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

这是我的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个回答

36

worker.conf文件中,您只需要更改此行:

stop on shutdown

收件人:

stop on stopping my-workers

my-workers.conf中的script改为pre-start

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

现在my-workers将保持状态: 因为工作发生在pre-start中,my-workers主进程不存在,因此也不会退出。stop on stopping my-workers会在停止my-workers时使工作者停止。当然,当它再次启动时,它将重新启动工作者。

(FYI,stop on shutdown无效,因为shutdown不是系统事件。查看man upstart-events获取所有定义的事件),因此您还应将my-workers更改为stop on runlevel [06]


4
我花了一些时间才明白你的意思,但是一旦我理解了...... 脑袋炸开 - Evgeny
@Evgeny 我也是,哈哈。如果像我和 Evgeny 一样,你刚花了5分钟试图理解这里发生了什么:基本上 my-workers.conf 会生成多个 upstart 脚本并退出,但现在每个 worker.conf 都有一行 stop on stopping my-workers,因此当您尝试停止已经停止的 my-workers 进程时,工作进程仍将监听它并死亡。因此,“重新启动” my-workers,即使它以前并没有真正运行,也会杀死工作进程(停止)并再次运行 pre-start 脚本(启动),从而再次生成它们。 - Mahn
1
它能工作,但是有点hackish。实际上,service my-workers start会挂起。Upstart文档指出:“所有作业文件必须具有exec或script stanza。”“pre-start script和post-stop script-事实上,它们不能启动进程。”也许最好只是为停止或重新启动工作程序创建另一个作业。 - Boris D. Teoharov
这现在被定义为抽象工作:http://upstart.ubuntu.com/cookbook/#abstract-job - 所以看起来没问题。 - amenthes

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

my-workers.conf文件中for循环的end似乎是错误的语法。我进行了替换。

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

并且它运行成功了!


1

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

stop on shutdown or workers-stop

然后你可以从命令行调用

sudo initctl emit workers-stop

您可以添加类似的事件来启动工作进程。为了实现重启所有工作进程,创建一个任务,该任务将发出 workers-stop 和 workers-start 事件。


1
基本上,您需要拥有一个执行所有N=1N=2组合的多个stopstart命令的过程。
一种简单的方法是在exec脚本中使用几个bash for循环。然而,如果进程需要一些时间来停止(例如,因为它们正在处理某些内容,并且在处理完当前作业后接受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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接