この回答で説明されているように、ワーカーの複数のインスタンスを実行しています: 複数のupstartインスタンスを自動的に開始します
質問:すべてのインスタンスを一度に再起動できますか?
私の労働者を始めるために私はすることができます:
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
worker.conf
では、次の行を変更する必要があります。
stop on shutdown
に:
stop on stopping my-workers
そして、script
の代わりにmy-workers.conf
を使用するように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、shutdown
はシステムイベントではないため、stop on shutdown
は何もしません。定義されたすべてのイベントに対してman upstart-events
)したがって、my-workersも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にもう1つのイベントを追加することを検討してください。
stop on shutdown or workers-stop
次に、コマンドラインから呼び出すことができます
Sudo initctl emit workers-stop
同様のイベントを追加して、ワーカーを開始できます。すべてのワーカーの再起動を実現するには、ワーカー停止イベントを発行してからワーカー開始イベントを発行するタスクを作成します。
基本的に、すべてのN=1
、N=2
の組み合わせに対して多くのstop
およびstart
コマンドを実行するプロセスが必要です。
これを行う簡単な方法は、exec script
スタンザ内の2つのbashfor
ループです。ただし、プロセスが停止するのに時間がかかる場合(たとえば、プロセスが何かに取り組んでいて、現在のジョブを処理した後に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