我正在运行这个答案中描述的一个worker的多个实例:自动启动多个upstart实例
问题:我可以一次重新启动所有实例吗?
为了启动我的员工,我可以这样做:
initctl启动我的工作者
然后允许我这样做:
initctl status worker N = 1 worker(1)启动/运行,进程551
initctl status worker N = 2 worker(2)启动/运行,进程552
有没有办法做这样的事情:
initctl重新启动我的工作人员
我希望能够重新启动所有的实例,而不必知道有多less人在运行。
这是我的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
在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-start
发生的, my-workers
主要工作不会存在,所以不会退出。 stop on stopping my-workers
导致工人停下来,只要my-workers
停下来。 当然,当它再次启动时,它将再次启动工人。
(仅供参考, stop on shutdown
不起作用,因为shutdown
不是一个系统事件,所有定义的事件都是man upstart-events
events),所以你也应该改变我的工作人员stop on runlevel [06]
我用上面的例子和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
它的工作!
考虑再向worker.conf添加一个事件:
stop on shutdown or workers-stop
然后你可以从命令行调用
sudo initctl emit workers-stop
你可以添加类似的事件来启动工人。 要实现重新启动所有的工人,就要创造一个任务,放出工人 – 停止,然后工人 – 开始事件。
基本上你需要有一个执行许多stop
和start
命令的进程,用于你所有的N=1
, N=2
组合。
一个简单的方法是在exec script
节中使用几个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 asynchronousously 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