ubuntu - regular - Reiniciar procesos de instancias Upstart
ubuntu medium free (4)
Considere agregar al evento worker.conf one more:
stop on shutdown or workers-stop
Entonces puedes llamar desde la línea de comando
sudo initctl emit workers-stop
Puede agregar eventos similares para iniciar a los trabajadores. Para lograr reiniciar, todos los trabajadores crean una tarea que emitirá trabajadores: detener y luego iniciar a los trabajadores.
Estoy ejecutando varias instancias de un trabajador como se describe en esta respuesta: Iniciar varias instancias upstart automáticamente
Pregunta: ¿Puedo reiniciar todas las instancias a la vez?
Para comenzar a mis trabajadores puedo hacer:
initctl start my-workers
Que luego me permite hacer:
trabajador de estado initctl N = 1 trabajador (1) inicio / ejecución, proceso 551
initctl status worker N = 2 worker (2) start / running, process 552
¿Hay alguna manera de hacer algo como esto?
initctl reiniciar mis-trabajadores
Me gustaría poder reiniciar todas las instancias sin tener que saber cuántas se están ejecutando.
Aquí está my 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
Y 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
En worker.conf
solo necesitas cambiar esta línea:
stop on shutdown
A:
stop on stopping my-workers
Y cambie my-workers.conf
para usar pre-start
lugar de script
:
pre-start script
for i in `seq 1 $NUM_WORKERS`
do
start worker N=$i
done
end script
Ahora my-workers
mantendrán el estado: dado que el trabajo ocurre en pre-start
, el proceso principal de my-workers
no existirá y por lo tanto no saldrá. stop on stopping my-workers
hace que los trabajadores se detengan cada vez que detienen a my-workers
. Luego, por supuesto, cuando se vuelva a encender, los trabajadores comenzarán nuevamente.
(Para su información, stop on shutdown
no hace nada, ya que shutdown
no es un evento del sistema. man upstart-events
para todos los eventos definidos) así que también debería cambiar my-workers para stop on runlevel [06]
Esencialmente necesitas tener un proceso que ejecute muchos comandos de stop
y start
para todas tus combinaciones N=1
, N=2
.
Una forma simple de hacer esto es un par de bash for
loops dentro de una estrofa de exec script
. Sin embargo, si los procesos toman algún tiempo para detenerse (por ejemplo, porque están trabajando en algo y están aceptando SIGTERM
después de haber procesado su trabajo actual), esto es ineficiente ya que tiene que esperar a que se detenga antes de enviar la señal al siguiente .
Por lo tanto, construí un script Upstart que los detiene en paralelo en https://github.com/elifesciences/builder-base-formula/blob/master/elife/config/etc-init-multiple-processes-parallel.conf
El script es compilado por Salt utilizando como entrada un mapa de nombres de procesos a cuántos hay allí. Aquí hay un resultado de muestra:
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
Lo intenté con el ejemplo de arriba y la respuesta de SpamapS, recibí:
init: my-workers pre-start process (22955) terminated with status 127
En /var/log/upstart/my-workers.log
encontré el problema:
/proc/self/fd/9: 6: /proc/self/fd/9: end: not found
El end
del for-loop en my-workers.conf
parecía ser una sintaxis incorrecta. Reemplacé
script
for i in `seq 1 $NUM_WORKERS`
do
start worker N=$i
done
end
end script
con
script
for i in `seq 1 $NUM_WORKERS`
do
start worker N=$i
done
end script
¡Y funcionó!