Pierwotnie zadałem to pytanie na StackOverflow. Potem zdałem sobie sprawę, że jest to prawdopodobnie lepsze miejsce.
Mam konfigurację bluepill do monitorowania moich opóźnionych procesów. (Aplikacja Ruby On Rails)
Korzystanie z Ubuntu 12.10.
Uruchamiam i monitoruję samą usługę bluepill przy użyciu Ubuntu upstart
. Moja konfiguracja upstart jest poniżej ( /etc/init/bluepill.conf
).
description "Start up the bluepill service"
start on runlevel [2]
stop on runlevel [016]
expect daemon
exec sudo /home/deploy/.rvm/wrappers/<app_name>/bluepill load /home/deploy/websites/<app_name>/current/config/server/staging/delayed_job.bluepill
# Restart the process if it dies with a signal
# or exit code not given by the 'normal exit' stanza.
respawn
Próbowałem też z expect fork
zamiast expect daemon
. Próbowałem też expect...
całkowicie usunąć linię.
Po uruchomieniu maszyny bluepill uruchamia się dobrze.
$ ps aux | grep blue
root 1154 0.6 0.8 206416 17372 ? Sl 21:19 0:00 bluepilld: <app_name>
PID procesu bluepill wynosi tutaj 1154. Ale upstart
wydaje się, że śledzi niewłaściwy PID. Śledzi PID, który nie istnieje.
$ initctl status bluepill
bluepill start/running, process 990
Myślę, że śledzi PID sudo
procesu, który rozpoczął proces bluepill.
Zapobiega to odrodzeniu się procesu bluepill, jeśli siłą zabiję go za pomocą kill -9
.
Co więcej, myślę, że z powodu śledzenia niewłaściwego PID, restart / wyłączenie po prostu zawiesza się i muszę za każdym razem mocno resetować maszynę.
Co może być tutaj problemem?
AKTUALIZACJA :
Problem pozostaje na dzień dzisiejszy (3 maja 2015 r.) W systemie Ubuntu 14.04.2.
Problem nie wynika z używania sudo. Nie używam już sudo. Moja zaktualizowana konfiguracja upstart to:
description "Start up the bluepill service"
start on runlevel [2]
stop on runlevel [016]
# Restart the process if it dies with a signal
# or exit code not given by the 'normal exit' stanza.
respawn
# Give up if restart occurs 10 times in 90 seconds.
respawn limit 10 90
expect daemon
script
shared_path=/home/deploy/websites/some_app/shared
bluepill load $shared_path/config/delayed_job.bluepill
end script
Po uruchomieniu komputera program ładuje się dobrze. Ale upstart nadal śledzi niewłaściwy PID, jak opisano powyżej.
Obejście wspomniane w komentarzach może rozwiązać problem z zawieszaniem się. Jednak tego nie próbowałem.
ps aux | grep 990
powinien to zrobić, alepstree 990
może być bardziej pouczający.Odpowiedzi:
Dość późno, ale mam nadzieję, że może to pomóc innym użytkownikom.
Istnieje udokumentowany błąd w fazie upstart, który może spowodować, że initctl będzie śledził niewłaściwy PID, jeśli podasz nieprawidłową
fork
sekcję w konfiguracji upstart: https://bugs.launchpad.net/upstart/+bug/406397Dzieje się tak, gdy upstart sprawdza
fork
zwrotkę i określa, ile rozwidlonych procesów powinien sprawdzić przed wybraniem „prawdziwego” PID kontrolowanego programu. Jeśli określiszexpect fork
lubexpect daemon
twój program nie rozwidla wystarczającej liczby razy,start
zawiesi się. Jeśli natomiast proces rozwidla się zbyt wiele razy,initctl
wyśledzi zły PID. Teoretycznie powinien to zostać udokumentowany w tej części książki kucharskiej , ale jak widać w tej sytuacji, PID jest związany z zabitym procesem, kiedy nie powinien.Konsekwencje tego wyjaśniono w komentarzach bugtrackera, ale streszczę tutaj: oprócz
initctl
niemożności zatrzymania procesu demona i utknięcia w nieudokumentowanym / nielegalnym stanie<service> start/killed, process <pid>
, jeśli proces należący do tego PID zatrzyma się (i zwykle będzie ), następnie PID zostaje zwolniony do ponownego wykorzystania przez system.Jeśli wydasz
initctl stop <service>
lubservice <service> stop
,initctl
zabije ten PID następnym razem, gdy się pojawi. Oznacza to, że gdzieś w dalszej części drogi, jeśli nie zrestartujesz się po popełnieniu tego błędu, następny proces użycia tego PID zostanie natychmiast zabity,initctl
nawet jeśli nie będzie to demon. Może to być coś tak prostegocat
lub tak złożonego, jak toffmpeg
, i trudno byłoby ustalić, dlaczego pakiet oprogramowania zawiesił się w trakcie rutynowej operacji.Problem polega na tym, że podałeś niewłaściwą
expect
opcję liczby rozwidleń faktycznie wykonywanych przez proces demona. Mówią, że istnieje poprawka przepisująca, która rozwiązuje ten problem, ale od wersji 1.8 (najnowszy Ubuntu 13.04 / styczeń 2014) problem nadal występuje.Ponieważ użyłeś
expect daemon
tego problemu i skończyłeś go, zalecamy wypróbowanieexpect fork
.Edycja: Oto skrypt kompatybilny z BASH Ubuntu ( oryginalny autorstwa Wade Fitzpatrick zmodyfikowany do używania Ubuntu
sleep
), który spawnuje procesy do wyczerpania dostępnej przestrzeni adresowej identyfikatora procesu, w którym to punkcie zaczyna się od 0 i przechodzi do „zablokowanego” PID Następnie odradza się proces, gdy PIDinitctl
jest rozłączany,initctl
zabija go i resetuje.źródło
Na podany przykład:
dla mnie szybkie rozwiązanie to:
źródło: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=582745#37
Mam nadzieję, że będzie to pomocne. To, co się dzieje, wyjaśniono w innych odpowiedziach.
źródło
reboot
Może czasami być korzystne i rozwiązuje również ten.Chyba że uruchamiasz zadanie na poziomie użytkownika Upstart lub używasz sekcji setuid - wtedy twoje zadanie działa jako root.
Skoro Upstart jest już uruchomiony jako root, dlaczego w ogóle musisz używać sudo
exec
?Używanie
sudo
lubsu
wexec
zwrotce spowodowało dla mnie te same problemy, które opisujesz tutaj.Zazwyczaj doświadczam przedmiotu 1 LUB zarówno 1 ORAZ 2:
Oczywiście dodatkowo musisz mieć
expect
zwrotkę odzwierciedlającą prawidłową liczbę widelców.YMMV, ale dla mnie:
exec
zwrotce z określoną liczbą widelców ogólnie skutkuje sytuacją 1 powyżej.exec
) powoduje sytuację 1 i 2 powyżej.źródło