2012-08-23 21 views
29
Upstart procesa

estoy corriendo varias instancias de un trabajador como se describe en esta respuesta: Starting multiple upstart instances automaticallyejemplo reinicio

Pregunta: ¿Puedo reiniciar todas las instancias a la vez?

Para iniciar mis trabajadores que puedo hacer:

initctl empezar mi de trabajo

que entonces permite que haga:

trabajador estado initctl N = 1 trabajador (1) iniciar/ejecutar, proceso 551

initctl status worker N = 2 worker (2) start/Marcha, proceso 552

¿Hay una manera de hacer algo como esto:

initctl reiniciar mi de trabajo

Me gustaría ser capaz de reiniciar todas las instancias sin tener para saber cuántos están corriendo.

Aquí es mi mi-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 

Respuesta

35

En worker.conf sólo tiene que cambiar esta línea:

stop on shutdown 

Para:

stop on stopping my-workers 

Y cambiar my-workers.conf utilizar pre-start en 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á Estado: ya que el trabajo que ocurre en pre-start, no existirá el proceso principal my-workers y por tanto no se cerrará. stop on stopping my-workers hace que los trabajadores se detengan cada vez que se detiene my-workers. Luego, por supuesto, cuando se vuelva a encender, los trabajadores comenzarán nuevamente.

(FYI, stop on shutdown no hace nada, ya que shutdown no es un evento del sistema.man upstart-events para todos los eventos definidos) por lo que también debe cambiar mis de trabajo para stop on runlevel [06]

+4

Me tomó un tiempo para entender lo que quieres decir, pero una vez que lo tengo ... * * mente soplado – Evgeny

+0

@Evgeny mismo aquí, jaja. Si como yo, y probablemente Evgeny, pasaste 5 minutos tratando de entender qué es lo que está sucediendo aquí: básicamente my-workers.conf genera múltiples scripts y ediciones upstart, pero cada worker.conf ahora tiene la línea 'stop on stopping my-workers ' ', así que cuando intentes detener el proceso de mis trabajadores ya detenido, los trabajadores aún lo escucharán y morirán. Así que "reiniciar" my-workers, aunque en realidad no se estaba ejecutando antes, tiene el efecto de matar a los trabajadores (detener) y ejecutar el script de pre-inicio (inicio) de nuevo, engendrando de nuevo. – Mahn

+1

Funciona, pero es bastante hackish. 'service my-workers start' se bloqueará, de hecho. La documentación de Upstart indica 'Todos los archivos de trabajo deben tener una secuencia de comandos o una secuencia de comandos.' Secuencia de comandos previa al inicio y secuencia de comandos post-parada: no se espera que estos inicien el proceso, de hecho, ¡no pueden! Tal vez es mejor crear otro trabajo para detener o reiniciar a los trabajadores. –

7

he probado con el ejemplo desde arriba y SpamapS respuesta, recibí:

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

En /var/log/upstart/my-workers.log he encontrado el problema:

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

el end del ciclo for en my-workers.conf parecía ser la sintaxis incorrecta. que sustituyen

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ó!

+1

¡Genial, funcionó para mí! –

1

considerar la adición a la worker.conf un evento más:

stop on shutdown or workers-stop 

A continuación, se puede llamar desde la línea de comandos

sudo initctl emit workers-stop 

Puede añadir evento similar para iniciar trabajadores. Para lograr reiniciar, todos los trabajadores crean una tarea que emitirá trabajadores: detener y luego iniciar a los trabajadores.

0

Esencialmente es necesario tener un proceso que se ejecuta muchos stop y start comandos para todas sus N=1, N=2 combinación.

Una manera simple de hacer esto es un par de bucles de bash for dentro de una estrofa 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, he construido un guión Upstart que los detiene de forma paralela al https://github.com/elifesciences/builder-base-formula/blob/master/elife/config/etc-init-multiple-processes-parallel.conf

El guión es compilada por el uso de la sal como entrada un mapa de nombres de proceso a cuántos están allí. Aquí es un resultado de la 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