Celery: Neustart von Sellerieproblemen und besser überwachte Konfigurationsdatei

Erstellt am 9. Mai 2010  ·  16Kommentare  ·  Quelle: celery/celery

Ich verwende die Supervisord-Konfigurationsdatei basierend auf dem Beispiel im Celery-Repository und habe einige Probleme, wenn ein Celeryd-Neustart erfolgt: Manchmal wird die Aufgabenverarbeitung nach dem Neustart von Sellerie ohne Fehlermeldungen in den Protokollen stillschweigend beendet. Prozesse bleiben in der Prozessliste sichtbar.

Schließlich habe ich herausgefunden, dass Sellerie manchmal, wenn Prozesse neu gestartet werden, zusätzliche Prozesse erzeugt, die nicht von Supervisor verwaltet werden, und dies führt zu diesen Fehlern. Also fing ich an, die Ausgabe ps nach jedem Neustart sorgfältig zu beobachten und zusätzliche Prozesse manuell über kill zu beenden. Nach dem Beenden dieser Prozesse werden die Aufgaben ordnungsgemäß ausgeführt. Dies ist eine Art Hack, der ein Problem für etwa eine Woche löst.

Und heute denke ich, dass der wahre Grund gefunden ist. Der voreingestellte überwachte Wert für die Option „stopwaitsecs“ ist 10 Sekunden. Dies bedeutet, dass der Sellerieprozess nach 10 Sekunden mit dem KILL-Signal anstelle von TERM beendet wird. Es scheint, dass Sellerie nicht gerne getötet wird und in diesem Fall versucht, zusätzliche Prozesse hervorzubringen.

Daher denke ich, dass es gut ist, so etwas wie 'stopwaitsecs=600' zu allen Supervisord-Beispielkonfigurationsdateien hinzuzufügen (aus der FAQ: "You should never stop celeryd with the KILL signal (-9), es sei denn, Sie haben TERM ein paar ausprobiert Mal und wartete ein paar Minuten, um ihm die Möglichkeit zu geben, herunterzufahren.") und untersuchen Sie das Verhalten von Sellerie beim KILL-Signal: Es wird in Dokumenten erwähnt, dass Aufgaben verloren gehen (und das ist in vielen Fällen tolerierbar), aber das Problem mit hervorgebracht wird Vorgang ist etwas seltsam.

Hilfreichster Kommentar

Falls Sie immer noch Probleme haben, Ihre Celery-Worker zu kündigen, können Sie versuchen, stopasgroup=true einzustellen, bevor Sie Ihre stopwaitsecs erhöhen.

Alle 16 Kommentare

Prozesse, die beim Empfang des KILL -Signals erzeugt werden, sind in der Tat seltsam. Ich sehe dieses Verhalten nicht, wenn es außerhalb von supervisord verwendet wird, also liegt es vielleicht daran?

Wenn Sie das setproctitle -Modul installieren, sollte Celery die Art des Prozesses in den ps -Auflistungen melden. Könnten Sie das tun, um zu untersuchen, welche Art von Prozess erstellt wird?

( easy_install setproctitle )

Das Setzen des Timeouts auf 600 ist wahrscheinlich gut. Gibt es eine Einstellung für unendlich (vielleicht mit einer Warnung, wenn es zu lange dauert)? Wenn celeryd über TERM (das bevorzugte Signal zum Herunterfahren) beendet wird, hört es auf, Nachrichten zu empfangen, und wartet darauf, dass die derzeit ausgeführten Aufgaben beendet werden. Und ich denke, für die meisten Anwendungen ist eine Beendigung mitten in der Ausführung nicht akzeptabel.

Was das Spawnen von Prozessen betrifft: Setproctitle und das Beobachten von Prozess-IDs waren hilfreich. Es ist kein Prozess-Spawning. Worker-Prozesse bleiben aktiv, wenn der übergeordnete Prozess beendet wird.
Dies ist eine Simulation eines überwachten Neustarts mit manuellem Beenden und Null-Timeout:

 4976 ?        Ss     0:00 /usr/bin/python /usr/bin/supervisord --pidfile /var/run/supervisord.pid
 5422 ?        S      0:01  \_ [celerybeat] --schedule=/var/lib/celery/celerybeat-schedule-nadovmeste --loglevel=INFO                                                             
 6101 ?        Sl     0:00  \_ [celeryd.MainProcess] Running... (--loglevel=INFO)                                                           
 6108 ?        S      0:00      \_ [celeryd.PoolWorker-1]                                                                                       
 nadovmeste:~# kill 6101 & kill -9 6101 &

ps -afx:

 4976 ?        Ss     0:00 /usr/bin/python /usr/bin/supervisord --pidfile /var/run/supervisord.pid
 5422 ?        S      0:01  \_ [celerybeat] --schedule=/var/lib/celery/celerybeat-schedule-nadovmeste --loglevel=INFO                                                             
 6867 ?        Sl     0:00  \_ [celeryd.MainProcess] Running... (--loglevel=INFO)                                                           
 6875 ?        S      0:00      \_ [celeryd.PoolWorker-1]                                                                                       
 6108 ?        S      0:00 [celeryd.PoolWorker-1]       

Ich konnte dies nur mit einem solchen künstlichen Rennen zwischen kill und kill -9 reproduzieren. Manchmal wird ein Arbeiter richtig getötet. Das Problem scheint Supervisor-spezifisch zu sein, denn wenn ich celeryd von der Konsole aus starte, habe ich kein Glück, es zu reproduzieren.

Ich konnte dies nach mehreren Versuchen mit von der Konsole gestarteten Skripten reproduzieren:

/home/nadovmeste/envs/nadovmeste/bin/python /home/nadovmeste/src/nadovmeste/manage.py celeryd -B --loglevel=INFO&

und dann in einer anderen Terminalsitzung:

nadovmeste:~# ps -afx

 6450 ?        Ss     0:00  \_ sshd: root@pts/2 
 6452 pts/2    Ss+    0:00      \_ -bash
 9343 pts/2    Sl     0:00          \_ [celeryd.MainProcess] Running... (-B --loglevel=INFO)                                                           
 9350 pts/2    S      0:00              \_ [celeryd.PoolWorker-2]                                                                                          
 9355 pts/2    S      0:00              \_ [celerybeat]     

nadovmeste:~# kill 9343 & kill -9 9343

nadovmeste:~# ps -afx

 4526 ?        Ss     0:00  \_ sshd: root@pts/1 
 4529 pts/1    Ss     0:00  |   \_ -bash
 9366 pts/1    R+     0:00  |       \_ ps -afx
 6450 ?        Ss     0:00  \_ sshd: root@pts/2 
 6452 pts/2    Ss+    0:00      \_ -bash    
 ...
 9350 pts/2    S      0:00 [celeryd.PoolWorker-2]                                                                                          
 9355 pts/2    S      0:00 [celerybeat]

Habe keine spezielle Option für unendliches Timeout mit Warnung in Supervisord-Dokumenten gefunden. Wahrscheinlich wird eine sehr große Anzahl ausreichen, wenn es das ist, was wir wollen.

Vielleicht hat es etwas mit Sellerybeat zu tun, weil ich das Problem für Konsolen gestartetes Sellerie erst reproduzieren konnte, nachdem ich die Option -B verwendet hatte.

Wenn ich einige Sellerieaufgaben lokal teste und die Option -B verwende, wird der Prozess manchmal nicht beendet, wenn ich Strg-C verwendet habe.

Ich kann das lokal nicht reproduzieren. Übrigens, betreibst du den Master-Zweig? Ich habe gerade einen Fehler behoben, der beim Herunterfahren hängen bleiben könnte. Wenn du das testen könntest, wäre das schön.

Ja, ich verwende den neuesten Master-Zweig. Ich habe Ihr Bugfixing-Commit gesehen und gehofft, dass es helfen wird, aber es scheint, dass es in meinem Fall nicht hilft: Der neueste Sellerie scheint sich genauso zu verhalten. Aber es ist möglich, dass das anfängliche Problem gelöst ist - ich überprüfe dies nur mit einem sofortigen Kill. Kann meine Hand jetzt nicht darum wickeln :) Das Strg-C-Problem ist mit meinem Setup nicht reproduzierbar.

Also der Fehlerbericht, vereinfacht: http://gist.github.com/401028 . Die Ergebnisse sind immer gleich (nicht manchmal). Ich habe einige periodische Aufgaben und einige nicht periodische. Die Aufgaben sind einfach und nehmen nicht viel Zeit in Anspruch. Ist es ein Fehler, dass untergeordnete Prozesse nach dem Beenden des Hauptprozesses am Leben bleiben? Wenn dies der Fall ist und Sie es nicht reproduzieren können, versuche ich, das Minimalprojekt bereitzustellen.

Das Verhalten beim Beenden von Celerybeat ist interessant: Wenn ich den hängenden (?) Celerybeat-Prozess beende, wird auch der hängende (?) Worker-Prozess heruntergefahren.

@kmike Ich kann mit den obigen Befehlen immer noch nicht reproduzieren. Vielleicht, weil ich OS X verwende, oder vielleicht, weil Sie Python 2.5 ausführen? (Ich verwende 2.6.1)

Könnte es mit --loglevel=DEBUG? ausführen. Es könnte einige Informationen darüber liefern, wo es aufhört.

Der Sellerybeat-Prozess wird vom Hauptprozess gestartet, also gehe ich davon aus, dass der Hauptprozess wartet
damit der Sellerieschlag beendet wird, bevor er die verbleibenden Pool-Prozesse beendet.

Ich dachte, dass der Hauptprozess beendet wurde: Er ist in der Prozessliste nicht sichtbar. Habe aber noch nicht viel Erfahrung mit Prozessmanagement.

Mein Setup war Debian Lenny + Python 2.5.

Ich werde versuchen, celeryd mit --loglevel=DEBUG auszuführen und auf meinem Macbook zu reproduzieren.

hm, du hast natürlich recht. Es ist fast so, als würde der Beat-Prozess die Pool-Prozesse übernehmen.

Ich habe gerade versucht, auf Debian Lenny mit Python 2.5 zu reproduzieren, und es funktioniert genau dort.
Versucht, sowohl mit TERM als auch mit INT zu töten.

Fragen Sie, danke für die Hilfe.

Ich denke, dass das anfängliche Problem mit einem erhöhten Supervisor-Timeout und Ihrem Bugfixing-Commit gelöst wurde. Die Simulation war falsch, weil ich kill -9 -Befehle verwende und sie ein KILL-Signal anstelle von TERM senden. Mit TERM werden Signalprozesse richtig getötet.

Supervisord verwendet das TERM-Signal, also sollte alles in Ordnung sein.

Aber was mich ein bisschen erschreckt, ist, dass der anfängliche Fehler nicht untersucht wurde. Ich versuche es zu reproduzieren und lasse es euch wissen.

Ah! Es tut mir Leid. Ich habe das Thema nicht aufmerksam genug gelesen. Ja! Genau das passiert, wenn Sie es mit SIGKILL töten. Das 9-Signal kann nicht abgefangen werden, also können wir AFAIK nichts dagegen tun.

Falls Sie immer noch Probleme haben, Ihre Celery-Worker zu kündigen, können Sie versuchen, stopasgroup=true einzustellen, bevor Sie Ihre stopwaitsecs erhöhen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen