2012-08-23 16 views
29

Sono in esecuzione più istanze di un lavoratore come descritto in questa risposta: Starting multiple upstart instances automaticallyesempio Riavvio Upstart elabora

Domanda: Posso riavviare tutte le istanze in una volta?

per iniziare il mio lavoro posso fare:

initctl iniziare la mia colleghi

Che poi mi permette di fare:

lavoratore stato initctl N = 1 lavoratore (1) start/running, processo 551

operaio di stato initctl N = 2 worker (2) start/Esecuzione, processo 552

C'è un modo per fare qualcosa di simile:

initctl riavviare il-lavoratori

Mi piacerebbe essere in grado di riavviare tutte le istanze, senza dover per sapere quanti sono in esecuzione.

Ecco il mio 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 

E 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 

risposta

35

In worker.conf è sufficiente modificare questa riga:

stop on shutdown 

A:

stop on stopping my-workers 

e cambiare my-workers.conf da usare al posto di pre-startscript:

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

Ora my-workers manterrà Stato: poiché il lavoro avviene in pre-start, il processo principale my-workers non esisterà e quindi non uscirà. stop on stopping my-workers provoca l'arresto dei lavoratori ogni volta che my-workers viene arrestato. Poi, naturalmente, quando si riavvierà, riavvierà nuovamente i lavoratori.

(FYI, stop on shutdown non fa nulla, come shutdown non è un evento di sistema.man upstart-events per tutti gli eventi definiti) così si dovrebbe anche cambiare i miei colleghi a stop on runlevel [06]

+4

ho messo un po 'per capire quello che vuoi dire, ma una volta che ho preso ... * mente soffiato * – Evgeny

+0

@Evgeny stesso qui, haha. Se come me, e probabilmente Evgeny, hai appena passato 5 minuti a cercare di capire cosa sta succedendo qui: fondamentalmente my-workers.conf genera più script e uscite di upstart, ma ogni worker.conf ora ha la linea 'stop per fermare i miei-worker ', quindi quando cerchi di fermare il processo dei miei lavoratori già fermato, i lavoratori lo ascolteranno e moriranno. Quindi "ricominciare" i miei lavoratori, anche se non era realmente in esecuzione prima, ha l'effetto di uccidere i lavoratori (stop) e di eseguire nuovamente lo script di pre-avvio (start), generandoli di nuovo. – Mahn

+1

Funziona ma è abbastanza hackerato. infatti, il servizio "my-workers start" verrà sospeso. La documentazione Upstart afferma che 'Tutti i file di lavoro devono avere una stanza exec o script.' 'Script di preavvio e script post-stop - Questi non dovrebbero avviare il processo, infatti, non possono. Forse è meglio solo creare un altro lavoro per fermare o riavviare i lavoratori. –

7

ho provato con l'esempio dall'alto e SpamapS risposta, ho ricevuto:

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

In /var/log/upstart/my-workers.log ho trovato il problema:

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

la end del ciclo for in my-workers.conf sembrava essere la sintassi sbagliata. Ho sostituito

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 

e ha funzionato!

+1

Ottimo, ha funzionato per me! –

1

considerare l'aggiunta al worker.conf un altro evento:

stop on shutdown or workers-stop 

quindi è possibile chiamare da linea di comando

sudo initctl emit workers-stop 

È possibile aggiungere evento simile per iniziare lavoratori. Per ottenere il riavvio di tutti i lavoratori, creare un'attività che emetterà i lavoratori-stop e quindi i lavoratori-avviano gli eventi.

0

In sostanza è necessario disporre di un processo che esegue molti stop e start comandi per tutto il vostro N=1, N=2 combinazione.

Un modo semplice per eseguire questa operazione è un paio di loop for bash all'interno di una stanza exec script. Tuttavia, se i processi richiedono un po 'di tempo per fermarsi (ad esempio perché stanno lavorando su qualcosa e stanno accettando SIGTERM dopo aver elaborato il loro lavoro corrente) questo è inefficiente in quanto bisogna aspettare che uno si fermi prima di inviare il segnale a quello successivo .

Pertanto, ho costruito uno script Upstart che li ferma in parallelo a https://github.com/elifesciences/builder-base-formula/blob/master/elife/config/etc-init-multiple-processes-parallel.conf

Lo script è compilato da Salt utilizzando come input una mappa di nomi di processo per quanti sono lì. Ecco il risultato del campione:

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