2012-08-23 15 views
29

Używam wielu wystąpień pracownika w sposób opisany w tej odpowiedzi: Starting multiple upstart instances automaticallyinstancja Ponowne uruchomienie Upstart przetwarza

Pytanie: Czy mogę ponownie uruchomić wszystkie instancje naraz?

Aby rozpocząć moje robotników mogę zrobić:

initctl rozpocząć moi pracownicy

Które następnie pozwala mi robić:

pracownik cywilny initctl n = 1 pracownika (1) start/uruchomiony, proces 551

pracownik statusu initctl N = 2 pracownik (2) start/Uruchomiony, proces 552

Czy istnieje sposób, aby zrobić coś takiego:

initctl restart moi pracownicy

Chciałbym, aby móc ponownie uruchomić wszystkie instancje bez konieczności wiedzieć, ile z nich działa.

Oto moja moja-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 

I 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 

Odpowiedz

35

W worker.conf po prostu trzeba zmienić tę linię:

stop on shutdown 

Do:

stop on stopping my-workers 

I zmienić my-workers.conf używać pre-start zamiast script:

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

Teraz my-workers zachowa stan: ponieważ praca dzieje w pre-start, główny proces my-workers nie będzie istnieć i tak nie wyjdzie. stop on stopping my-workers powoduje zatrzymanie pracowników po zatrzymaniu my-workers. Wtedy oczywiście, kiedy znowu się uruchomi, ponownie rozpocznie robotników.

(FYI, stop on shutdown nic nie robi, ponieważ shutdown nie jest zdarzeniem systemowym.man upstart-events dla wszystkich zdefiniowanych zdarzeń), więc należy również zmienić MY-robotników do stop on runlevel [06]

+4

Zajęło mi trochę czasu, aby zrozumieć, co to znaczy, ale kiedy mam go ... * umysł dmuchane * – Evgeny

+0

@Evgeny samo tutaj, haha. Jeśli tak jak ja i prawdopodobnie Jewgienij, spędziłeś tylko 5 minut próbując zrozumieć, co się tutaj dzieje: w zasadzie my-workers.conf spawnuje wiele skryptów i wyjść z wyprzedzeniem, ale każdy plik worker.conf ma teraz linię 'zatrzymaj się przy zatrzymywaniu moich pracowników ', więc kiedy spróbujesz zatrzymać proces, który już powstrzymał proces moich pracowników, robotnicy nadal będą go słuchać i umrzeć. Tak więc "ponowne uruchomienie" moich pracowników, nawet jeśli wcześniej tak naprawdę nie działało, skutkuje ponownym zabiciem robotników (zatrzymaniem) i ponownym uruchomieniem skryptu przed uruchomieniem (start), i ponownym uruchomieniem. – Mahn

+1

Działa, ale jest dość hackish. 'service my-workers start' zawiesza się. Dokumentacja Upstart stwierdza, że ​​"Wszystkie pliki zadań muszą zawierać albo skrypt przed uruchomieniem, albo skrypt post-stop. Nie oczekuje się, że zaczną proces, w rzeczywistości nie mogą tego zrobić". Może lepiej jest po prostu stworzyć kolejną pracę do zatrzymania lub ponownego uruchomienia pracowników. –

7

Próbowałem go z przykładu z góry i SpamapS odpowiedzi dostałam:

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

W /var/log/upstart/my-workers.log znalazłem problem:

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

end z pętli for w my-workers.conf wydawało się źle składnia. Wymieniłem

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

z

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

i to działa!

+1

Świetnie, pracował dla mnie! –

1

rozważyć dodanie do worker.conf jedno wydarzenie:

stop on shutdown or workers-stop 

Następnie można wywołać z linii poleceń

sudo initctl emit workers-stop 

Możesz dodać podobną imprezę, aby rozpocząć pracowników. Aby osiągnąć ponowne uruchomienie, wszyscy pracownicy tworzą zadanie, które będzie emitować pracowników - zatrzymać, a następnie uruchomić pracowników.

0

Zasadniczo trzeba mieć proces, który wykonuje wiele stop i start polecenia dla całego N=1, N=2 kombinacji.

Prostym sposobem na to jest kilka pętli for bash wewnątrz exec script zwrotki. Jeśli jednak zatrzymanie procesów zajmie trochę czasu (np. Ponieważ pracują nad czymś i akceptują one SIGTERM po przetworzeniu ich bieżącego zadania), jest to nieefektywne, ponieważ trzeba czekać aż się zatrzyma przed wysłaniem sygnału do następnego. .

Dlatego zbudował Upstart skrypt, który zatrzymuje je równolegle na https://github.com/elifesciences/builder-base-formula/blob/master/elife/config/etc-init-multiple-processes-parallel.conf

Skrypt jest kompilowany przez sól stosując jako wkład mapa nazwisk procesowych na ile istnieją. Oto przykładowy wynik:

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 
Powiązane problemy