Gunicorn: Gunicorn Sync-Worker-Zeitüberschreitung bei Docker + AWS

Erstellt am 29. Jan. 2016  ·  78Kommentare  ·  Quelle: benoitc/gunicorn

Wenn ich gunicorn 19.4.5 in einem Docker-Image verwende, das unter Ubuntu 14.04 LTS auf AWS ausgeführt wird, sehe ich konstante Worker-Timeouts, wenn ich mit > 1 Sync-Worker und der standardmäßigen 30s-Timeout-Periode ausgeführt werde. Dies kann mit #588 oder #942 zusammenhängen, obwohl dies eine wesentlich neuere Version von Gunicorn ist, so dass ich es nicht genau sagen konnte.

Indizien aus mehreren Durchläufen scheinen darauf hinzudeuten, dass einer der Arbeiter nicht betroffen ist und nur die verbleibenden N-1 Arbeiter versagen und neu starten. Ich konnte jedoch nur wenige Datenpunkte erhalten, die dies nahelegen, also nicht als starkes Signal verstehen.

Hier sind Dinge, die ich überprüft habe:

  • Treten die Probleme außerhalb von Docker auf oder wenn dasselbe Docker-Image verwendet wird, jedoch nicht in AWS?
    Nein, ich konnte das Problem nur mit Docker auf AWS replizieren.
  • Dauert die Initialisierung der Anwendung >30s?
    Nein, die Initialisierung der Anwendung ist in weniger als 1 Sekunde abgeschlossen.
  • Erhält die Anwendung eine Anfrage, die zum Aufhängen führt?
    Das Problem tauchte auf, ohne dass Anfragen an die Anwendung gestellt wurden.
  • Hat die Anwendung einen fehlerhaften Initialisierungscode, der Gunicorn verwirrt?
    Das Problem trat auf, wenn gunicorn in derselben Konfiguration (mit > 1 Sync-Worker), aber mit einer anderen Anwendung ausgeführt wurde. Diese neue Anwendung läuft ohne Probleme auf gunicorn, wenn Sie gevent-Worker verwenden.
  • Kann das Dateisystem von Docker die ctime nicht aktualisieren?
    Siehe das folgende Protokoll - die ctime scheint normalerweise gut voranzukommen. Das Dateisystem von Docker lässt stat -L für gelöschte Dateien nicht zu, aber das Verhindern, dass gunicorn die Verknüpfung der Datei aufhebt, führt auch dazu, dass stat -L anzeigt, dass ctime wie gewohnt aktualisiert wird.

Ich habe workertmp.py Code hinzugefügt, um die gelesene ctime bei jeder Überprüfung zu protokollieren, und hier ist ein solches Protokoll (zwischen allen Arbeitern verschachtelt):

[2016-01-29 00:21:38 +0000] [3238] [INFO] Starting gunicorn 19.4.0
[2016-01-29 00:21:38 +0000] [3238] [INFO] Listening at: http://0.0.0.0:5000 (3238)
[2016-01-29 00:21:38 +0000] [3238] [INFO] Using worker: sync
[2016-01-29 00:21:38 +0000] [3243] [INFO] Booting worker with pid: 3243
[2016-01-29 00:21:38 +0000] [3244] [INFO] Booting worker with pid: 3244
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026899.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026899.03
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026900.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026899.03
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026900.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026899.03
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026900.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026899.03
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026900.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026899.03
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026904.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026899.03
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026904.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026905.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026904.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026905.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026904.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026905.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026904.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026905.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026904.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026909.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026910.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026909.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026910.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026909.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026910.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026909.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026910.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026909.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026914.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026933.73
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026934.74
FOOBAR: modify /tmp/wgun[2016-01-29 00:22:25 +0000] [3238] [CRITICAL] WORKER TIMEOUT (pid:3243)
[2016-01-29 00:22:25 +0000] [3243] [INFO] Worker exiting (pid: 3243)
[2016-01-29 00:22:25 +0000] [3330] [INFO] Booting worker with pid: 3330
icorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026935.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026935.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026935.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026935.0
FOOBAR: modify /tmp/wgunic54026934.74
FOOBAR: modify /tmp/wgun[2016-01-29 00:22:25 +0000] [3238] [CRITICAL] WORKER TIMEOUT (pid:3243)
[2016-01-29 00:22:25 +0000] [3243] [INFO] Worker exiting (pid: 3243)
[2016-01-29 00:22:25 +0000] [3330] [INFO] Booting worker with pid: 3330
icorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time:fy] [3238] [CRITICAL] WORKER TIMEOUT (pid:3243)
[2016-01-29 00p/2:25 +0000] [3243] [INFO] Worker exiting (pid: 3243)
[2016-0ic29 00:22:25 +0000] [3330] [INFO] Booting worker with pid: 33myicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorntiyjLwI time: 1454026935.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt45ime: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026945.82
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026946.01
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026946.01
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026946.01
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8corn-myjLwI time:fy] [3238] [CRITICAL] WORKER TIMEOUT (pid:32BA)
[2016-01-29 00p/2:25 +0000] [3243] [INFO] Worker exiting (pdify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
FOOBAR: modify /tmp/wgunicorn-Mw64T1 timeodify /tmp/wgunicorn-myjLwI time: 1454026964.74
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026965.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026965.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026965.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026965.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026969.74
FOO[2016-01-29 00:22:59 +0000] [3238] [CRITICAL] WORKER TIMEOUT (pid:3330)
[2016-01-29 00:22:59 +0000] [3330] [INFO] Worker exiting (pid: 3330)
icorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026935.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026935.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026935.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026935.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026939.74
FOOBAR: modify /tmp/wgunicorn-LwI time: 1454026965.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 tI time: 1454026940.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026940.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026940.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026940.0
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026944.74
FOOBAR: modify /tmp/wgunicorn-RhAFmt time: 1454026915.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.0
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026945.8
[2016-01-29 00:22:59 +0000] [3396] [INFO] Booting worker with pid: 3396
BAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjL26949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjL26949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjL26949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjL26949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjL26949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
FOOBAR: modify /tmp/wgunicorn-myjL26949.74
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
FOOBAR: modify /tmp/w79.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026979.97
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
80.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454029.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454029.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454029.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026979.95
FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
 WORKER TIMEOUT (pid:3396)
 [2016-01-29 00:23:31 +0000] [3396] [INFO] Worker exiting (pid: 3396)
 BAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026970.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026974.74
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-Mw64T1 time: 1454026949.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454026975.0
 FOOBAR: modify /tmp/wgunicorn-Mw6nicorn-k3uZLy time: 1454026980.16
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027005.0
 FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027010.0
 FOOBAR: modify /tmp/wgunicorn-k3uZLy time: 1454026980.16
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027010.0
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027011.08
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027011.28
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027011.28
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027011.28
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmprn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-Znicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027011.06
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027028.98
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027030.0
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027030.0
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wguicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027030.0
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027030.0
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wguicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027030.0
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027030.0
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wguicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027030.0
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn--ZmVaVS time: 1454027014.74
 FOOBAR: modify /tmp/wgunicorn-myjLwI time: 1454027035.0
 FOOBAR: modify /tmp/wgunicorn-ZmVaVS time: 1454027014.74
 FOOBAR: modify /t[2016-01-29 00:24:05 +0000] [3238] [CRITICAL] WORKER TIMEOUT (pid:3453)
 [2016-01-29 00:24:05 +0000] [3453] [INFO] Worker exiting (pid: 3453)
FeaturIPC PlatforDocker - Bugs -

Hilfreichster Kommentar

Versuchen Sie es stattdessen mit den gevent Workern, dies hat das Problem für mich gelöst.

Alle 78 Kommentare

hrmmm aus dem obigen Log kann ich sehen, dass sich die Zeit nie ändert. Ich werde überprüfen

Danke, ich weiß es zu schätzen!

Ich könnte von diesem Fehler betroffen sein.

Ich führe gunicorn in einem Docker-Image auf AWS (Elastic Beanstalk + EC2 Container Service) aus.
Es gibt ständige Worker-Timeouts, die fast unmittelbar nach der Initialisierung auftreten und nur beim Ausführen des Docker-Images auf AWS.
Die gleiche HTTP-Anfrage dauert manchmal einige ms, manchmal 20-30 Sekunden. Egal, ob es sich um eine nicht vorhandene Seite, eine einfache nicht authentifizierte "Hello world"-String-Seite oder eine Seite handelt, die Datensätze aus einer Datenbank abruft.

Zusätzliche Details :

  • Gunicorn-Versionen : 19.5.0 und 19.6.0.
  • Basis-Docker-Image : python:3.4 ( Betriebssystem : Debian Jessie)
  • Docker-Version : 1.9.1 (verwaltet von Amazon ECS), Betriebssystem : Amazon Linux AMI 2016.03 (verwaltet von Amazon EB).
  • Webanwendungs-Framework : Django-Versionen 1.9.6 und 1.9.7.

Umgebungen _nicht_ betroffen :

  • Lokaler Computer , sowohl _inside_ als auch _outside_ ein Docker-Container. Betriebssystem : Ubuntu 16.04 LTS, Docker : 1.11.2.
  • Heroku ( Betriebssystem : Ubuntu 14.04 LTS)

Amazon-Containerprotokolle :

[2016-06-15 16:46:15 +0000] [1] [DEBUG] Current configuration:
  cert_reqs: 0
  post_request: <function PostRequest.post_request at 0x7fb13e187c80>
  worker_connections: 1000
  tmp_upload_dir: None
  enable_stdio_inheritance: False
  timeout: 30
  pre_fork: <function Prefork.pre_fork at 0x7fb13e1871e0>
  worker_int: <function WorkerInt.worker_int at 0x7fb13e1876a8>
  backlog: 2048
  max_requests: 0
  max_requests_jitter: 0
  access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
  logconfig: None
  syslog_addr: udp://localhost:514
  preload_app: False
  pidfile: None
  umask: 0
  secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}
  paste: None
  proxy_protocol: False
  worker_class: sync
  on_starting: <function OnStarting.on_starting at 0x7fb13e414c80>
  worker_abort: <function WorkerAbort.worker_abort at 0x7fb13e187840>
  worker_exit: <function WorkerExit.worker_exit at 0x7fb13e187e18>
  config: config/gunicorn.py
  nworkers_changed: <function NumWorkersChanged.nworkers_changed at 0x7fb13e18a048>
  daemon: False
  accesslog: None
  errorlog: -
  loglevel: debug
  syslog_prefix: None
  ssl_version: 3
  suppress_ragged_eofs: True
  limit_request_field_size: 8190
  reload: False
  logger_class: gunicorn.glogging.Logger
  statsd_host: None
  keyfile: None
  raw_env: []
  threads: 1
  django_settings: None
  proc_name: None
  proxy_allow_ips: ['127.0.0.1']
  limit_request_fields: 100
  ciphers: TLSv1
  check_config: False
  do_handshake_on_connect: False
  post_worker_init: <function PostWorkerInit.post_worker_init at 0x7fb13e187510>
  graceful_timeout: 30
  worker_tmp_dir: None
  certfile: None
  sendfile: None
  keepalive: 2
  chdir: /app/testapp
  when_ready: <function WhenReady.when_ready at 0x7fb13e187048>
  ca_certs: None
  on_exit: <function OnExit.on_exit at 0x7fb13e18a1e0>
  spew: False
  bind: [':8000']
  post_fork: <function Postfork.post_fork at 0x7fb13e187378>
  limit_request_line: 4094
  syslog_facility: user
  workers: 3
  syslog: False
  pre_request: <function PreRequest.pre_request at 0x7fb13e187b70>
  user: 0
  group: 0
  forwarded_allow_ips: ['127.0.0.1']
  pythonpath: None
  on_reload: <function OnReload.on_reload at 0x7fb13e414e18>
  pre_exec: <function PreExec.pre_exec at 0x7fb13e1879d8>
  default_proc_name: config.wsgi
  statsd_prefix: 
[2016-06-15 16:46:15 +0000] [1] [INFO] Starting gunicorn 19.5.0
[2016-06-15 16:46:15 +0000] [1] [DEBUG] Arbiter booted
[2016-06-15 16:46:15 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1)
[2016-06-15 16:46:15 +0000] [1] [INFO] Using worker: sync
[2016-06-15 16:46:15 +0000] [8] [INFO] Booting worker with pid: 8
[2016-06-15 16:46:15 +0000] [9] [INFO] Booting worker with pid: 9
[2016-06-15 16:46:15 +0000] [10] [INFO] Booting worker with pid: 10
[2016-06-15 16:46:15 +0000] [1] [DEBUG] 3 workers
[2016-06-15 16:46:52 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:9)
[2016-06-15 16:46:52 +0000] [9] [INFO] Worker exiting (pid: 9)
[2016-06-15 16:46:52 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:10)
[2016-06-15 16:46:52 +0000] [10] [INFO] Worker exiting (pid: 10)
[2016-06-15 16:46:53 +0000] [20] [INFO] Booting worker with pid: 20
[2016-06-15 16:46:53 +0000] [1] [DEBUG] 2 workers
[2016-06-15 16:46:53 +0000] [21] [INFO] Booting worker with pid: 21
[2016-06-15 16:46:53 +0000] [1] [DEBUG] 3 workers
[2016-06-15 16:47:23 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:8)
(...)

`

Vielen Dank.

Das sehe ich auch. Mein Verdacht ist der Elastic Load Balancer. Wir haben in einer früheren Firma paste und dies verursachte Probleme mit dem ELB. Ich glaube, es verwendet Verbindungen irgendwie wieder und dies verursachte Schluckauf in paste .

Ich bin jetzt in einem neuen Job, wo wir gunicorn benutzen und alles war in Ordnung, bis wir begannen, den Server hinter eine ELB zu stellen, die Webapp ist jetzt oft sehr unansprechbar und scheint zu hängen.

Versuchen Sie es stattdessen mit den gevent Workern, dies hat das Problem für mich gelöst.

Ist dies also ein Problem damit, dass die ELB die Verbindungen am Leben hält und den Sync-Worker bindet? Das würde mir sehr seltsam vorkommen, da wir bewusst signalisieren, dass die Verbindung mit dem Sync-Worker geschlossen werden soll: https://github.com/benoitc/gunicorn/blob/master/gunicorn/workers/sync.py#L168

Wir könnten die Verbindung aber bewusst schließen. Wenn jemand testen möchte, ob der Aufruf von client.close() bedingungslos ist, könnte dies ein interessanter Test sein: https://github.com/benoitc/gunicorn/blob/master/gunicorn/workers/sync.py#L199

Sie können auch sicherstellen, dass das Leerlauf-Timeout auf dem ELB niedriger ist als das Worker-Timeout, um schnell zu überprüfen, ob dies sogar die Ursache des Problems ist: http://docs.aws.amazon.com/elasticloadbalancing/latest/ classic/config-idle-timeout.html

@tilgovi das gevent Worker behoben wird. Aber andererseits, wer weiß..

es passiert nur hinter ELB und wenn das Protokoll HTTP oder HTTPS auf ELB eingestellt ist.
Wenn Sie das Protokoll auf TCP oder SSL ändern, verschwindet das Problem.
Weiß jemand, wie man das Problem mit Sync-Workern beheben kann? Ich habe den beschriebenen Fix (TCP statt HTTP) bis jetzt verwendet, wenn ich Zugriffsprotokolle überwachen und den X-Forwarded-For-Header sehen werde, der nur für HTTP/HTTPS auf ELB aktiviert ist :)

Seltsam, nur um sicherzustellen, dass wir auf der gleichen Seite sind, bedeutet dies, dass es eine Art Optimierung gibt, wenn die HTTP/HTTPS-Option im ELB verwendet wird? Und diese Optimierung verursacht Probleme mit den Sync-Workern?

@ecs Ich denke, im Falle eines HTTP / HTTPS-Load-Balancers wird dieselbe TCP-Verbindung wiederverwendet, die von ELB lange Zeit am Leben gehalten wird - so etwas. Aber es erklärt nicht, warum gevent worker gut funktioniert ... (obwohl ich gevent noch nicht getestet habe, lese einfach aus diesen Kommentaren)

Übrigens, es gibt sicherlich viele Faktoren (Gunicorn-Version, Arbeiterklasse, Inside Docker oder nicht, ELB-Protokoll), die einen Einfluss haben können, daher könnte es großartig sein, wenn jemand testet und bestätigt, dass das TCP-Protokoll auf ELB im Gegensatz zu HTTP funktioniert. Ich teste auf Docker, das auf Ubuntu 14.04 und Gunicorn Version 19.3.0 gehostet wird

Ich habe das gleiche Problem:
[2016-10-03 12:13:17 +0000] [6] [KRITISCH] WORKER TIMEOUT (pid:16)
[2016-10-03 12:13:17 +0000] [16] [INFO] Arbeiter verlassen (pid: 16)
[2016-10-03 12:13:17 +0000] [6] [KRITISCH] WORKER TIMEOUT (pid:20)
[2016-10-03 12:13:17 +0000] [20] [INFO] Arbeiter verlassen (pid: 20)
[2016-10-03 12:13:17 +0000] [33] [INFO] Booten des Workers mit pid: 33

Meine Einrichtung.

Ich verwende kube-aws, um einen Kubernetes-Cluster mit core-os auf AWS einzurichten: https://github.com/coreos/coreos-kubernetes/tree/master/multi-node/aws

Ich habe eine Python-App mit Gunicorn und Sync-Workern. Der Dienst für sie verwendet einen HTTPS-Load-Balancer mit dem Zertifikat meiner Sites. Alle Worker gelten nach der standardmäßigen Timeout-Zeit von 30 Sekunden als abgelaufen, wie es scheint. Sie werden schließlich alle neu gestartet. Kubernetes startet den Container schließlich neu, wenn er beendet wird. Diese Neustarts erfolgen kontinuierlich. Jemand oben erwähnte, dass gevent das Problem löst. Ich kann das ausprobieren, aber ich würde wirklich gerne verstehen, warum dies geschieht.

Wir sehen dieses Problem derzeit auch, ich werde versuchen, weitere Details zu posten, wenn ich die Gelegenheit dazu habe. Es hängt mit dem Sync-Worker zusammen, da der Wechsel zu Gevent das Problem tatsächlich löst. Dies ist auf AWS mit ECS und ELB.

Hatte das gleiche seltsame Problem auch mit einer unserer Apps. Das Ändern von Listenern von HTTP zu TCP löst das Problem tatsächlich.

Kann mir jemand eine Schritt-für-Schritt-Anleitung geben, um das Problem zu reproduzieren? (Konfigurationsschritt und so) Oder zeigen Sie mir zumindest eine einfache Möglichkeit, diese Umgebung einzurichten :) Ich werde mir diese Woche einen Blick darauf werfen.

Wenn Sie sich für einen solchen Balancer auf HTTP verlassen, müssen Sie im Allgemeinen Keep-Alive-Back (mit Ausnahme von TCP) verarbeiten, sodass alles, was einen Sync-Worker verwendet, ein Problem sein kann, bis der Sync-Worker für seine Unterstützung aktualisiert wird.

Lass es mich auf jeden Fall wissen.

Richten Sie einfach eine grundlegende Flask-App ein und führen Sie sie mit gunicorn mit Sync-Workern im Docker auf AWS aus, mit HTTP-Load-Balancing und der Konfiguration von oben:

Wenn ich gunicorn 19.4.5 in einem Docker-Image verwende, das unter Ubuntu 14.04 LTS auf AWS ausgeführt wird, sehe ich konstante Worker-Timeouts, wenn ich mit > 1 Sync-Worker und der standardmäßigen 30s-Timeout-Periode ausgeführt werde.

Sie müssen keine Anfragen an die Anwendung stellen, überwachen Sie einfach die Protokolle und Sie werden feststellen, dass die Worker das Zeitlimit überschreiten.

  • Ich kann dieses Verhalten sowie die grundsätzliche Herangehensweise, es zu reproduzieren, bestätigen.

    • Das Verhalten ist nicht auf Docker beschränkt, sondern auf den Sync-Worker / die Keepalive-Einstellung, daher könnten Sie in Betracht ziehen, den Titel zu ändern ...

  • Ich habe die Keepalive-Einstellung geändert, um der hier beschriebenen zu folgen: https://serverfault.com/questions/782022/keepalive-setting-for-gunicorn-behind-elb-ohne-nginx/ (der interessanteste Teil ist das Zitat aus der AWS ELB-Dokumentation) und stellte fest, dass der Server dieses Verhalten nicht mehr zeigt.
  • Außerdem bin ich zusätzlich in die gthread-Worker-Klasse gewechselt und fand das Ergebnis bisher sehr akzeptabel.

Ich verwende derzeit gevent-Worker mit einer Zeitüberschreitung von 65 Sekunden (AWS ELB-Zeitüberschreitung beträgt 60 Sekunden, AFAIK). Ich erlebe manchmal immer noch 504-Fehler, selbst wenn nur ein Client Anfragen stellt, wobei jeweils eine Anfrage ausgeführt wird, aber ich konnte noch keinen Grund festlegen.

@obi1kenobi Haben Sie versucht, das Keepalive über die ELB-Timeout-Option hinaus zu erhöhen?

@lenucksi das Keepalive ist bereits um 5s höher als das ELB-Timeout -- hoffentlich fahren die Uhren der Server nicht ganz so viel :)

Auch ich bin auf dieses Problem gestoßen, als ich gunicorn 19.6 in einem Docker-Container auf einer EC2-Instance hinter einem ELB ausgeführt habe (unter Verwendung des Standard-HTTP-Protokolls für das Reverse-Proxy an die EC2-Instance).

Wie zuvor vorgeschlagen, hat das Festlegen der Worker-Klasse auf gevent dieses Problem für mich behoben (wo ich zuvor die Standard-Worker-Klasse sync ).

Ich werde versuchen, ein Minimalbeispiel zu dokumentieren, um das Problem zu reproduzieren.

Um das zu bestätigen, was andere gesagt haben, scheint die ELB eine Verbindung zur EC2-Instanz zu öffnen und sie so offen zu halten, dass Gunicorn davon abgehalten wird, zusätzliche Anfragen zu bearbeiten.

Wenn diese gehaltene Verbindung beendet wird, weil Gunicorn die Anforderung von der ELB ausschaltet, schlagen alle ausstehenden Anforderungen, die sich dahinter in der Warteschlange befinden, ebenfalls fehl (einschließlich der Zustandsprüfung der ELB, wodurch die Instanz aus dem ELB entfernt wird, was das Debuggen erschwert; ) ).

Dieses Symptom deutet darauf hin, dass dies ein Duplikat dessen ist, was in dieser vorherigen Ausgabe beobachtet wurde und nichts mit Docker zu tun hat: https://github.com/benoitc/gunicorn/issues/588

@jelis Wissen Sie, ob dies mit einer Kubernetes-Konfiguration zusammenhängt? Wurde Ihr Problem gelöst?

Ich bin auch auf einem ELB mit SSL-Terminierung. Ich sehe das in meinen Logs:

[017-03-01 07:36:32 +0000] [1249] [DEBUG] GET /healthcheck
[01/Mar/2017:07:36:32 +0000] "GET /healthcheck HTTP/1.1" 200 22 "-" "ELB-HealthChecker/1.0"
[017-03-01 07:36:37 +0000] [12] [CRITICAL] WORKER TIMEOUT (pid:1203)
[017-03-01 07:36:37 +0000] [12] [CRITICAL] WORKER TIMEOUT (pid:1225)
[017-03-01 07:36:37 +0000] [12] [CRITICAL] WORKER TIMEOUT (pid:1234)
[017-03-01 07:36:37 +0000] [12] [CRITICAL] WORKER TIMEOUT (pid:1243)
[017-03-01 07:36:37 +0000] [1203] [INFO] Worker exiting (pid: 1203)
[017-03-01 07:36:37 +0000] [1225] [INFO] Worker exiting (pid: 1225)
[017-03-01 07:36:37 +0000] [1243] [INFO] Worker exiting (pid: 1243)
[017-03-01 07:36:37 +0000] [1234] [INFO] Worker exiting (pid: 1234)
[017-03-01 07:36:37 +0000] [1256] [INFO] Booting worker with pid: 1256
[017-03-01 07:36:37 +0000] [12] [DEBUG] 14 workers
[017-03-01 07:36:37 +0000] [1257] [INFO] Booting worker with pid: 1257
[017-03-01 07:36:37 +0000] [1262] [INFO] Booting worker with pid: 1262
[017-03-01 07:36:37 +0000] [1265] [INFO] Booting worker with pid: 1265
[017-03-01 07:36:37 +0000] [12] [DEBUG] 16 workers
[017-03-01 07:36:40 +0000] [1262] [DEBUG] GET /healthcheck

Update - Ich habe gerade von gunicorn zu gevent gewechselt (http://flask.pocoo.org/docs/0.12/deploying/wsgi-standalone/#gevent) und das Problem ist behoben. Dies bezieht sich auf meinen obigen Kommentar https://github.com/benoitc/gunicorn/issues/1194#issuecomment -283269046

Ich hämmere seit ein paar Tagen an diesem Thema. Die Notizen aller hier sind fantastisch und geben uns eine Reihe von Möglichkeiten, um Korrekturen/Problemumgehungen/Mitigationen zu verfolgen. (das Protokoll meiner Arbeit ist im Bug wir Tracking hier )

Ich habe gerade versucht, gevent mit einer Erhöhung der Arbeiterzahl zu verwenden, und das hat uns überhaupt nicht geholfen - tatsächlich sah es überraschenderweise schlimmer aus - alle fünf gevent-Mitarbeiter starben gleichzeitig ab, was ein neues Verhalten von was ich oben gelesen habe:

[2017-03-30 23:38:37 +0000] [5] [INFO] Starting gunicorn 19.7.1
[2017-03-30 23:38:37 +0000] [5] [INFO] Listening at: http://0.0.0.0:8000 (5)
[2017-03-30 23:38:37 +0000] [5] [INFO] Using worker: eventlet
[2017-03-30 23:38:38 +0000] [8] [INFO] Booting worker with pid: 8
[2017-03-30 23:38:40 +0000] [9] [INFO] Booting worker with pid: 9
[2017-03-30 23:38:41 +0000] [11] [INFO] Booting worker with pid: 11
[2017-03-30 23:38:42 +0000] [12] [INFO] Booting worker with pid: 12
[2017-03-30 23:38:42 +0000] [10] [INFO] Booting worker with pid: 10
[2017-03-30 23:40:08 +0000] [5] [CRITICAL] WORKER TIMEOUT (pid:8)
[2017-03-30 23:40:12 +0000] [5] [CRITICAL] WORKER TIMEOUT (pid:9)
[2017-03-30 23:40:12 +0000] [5] [CRITICAL] WORKER TIMEOUT (pid:10)
[2017-03-30 23:40:12 +0000] [5] [CRITICAL] WORKER TIMEOUT (pid:11)
[2017-03-30 23:40:12 +0000] [5] [CRITICAL] WORKER TIMEOUT (pid:12)
[2017-03-30 23:40:13 +0000] [8] [INFO] Worker exiting (pid: 8)
[2017-03-30 23:40:13 +0000] [10] [INFO] Worker exiting (pid: 10)
[2017-03-30 23:40:16 +0000] [16] [INFO] Booting worker with pid: 16
[2017-03-30 23:40:16 +0000] [17] [INFO] Booting worker with pid: 17
[2017-03-30 23:40:18 +0000] [18] [INFO] Booting worker with pid: 18
[2017-03-30 23:40:20 +0000] [19] [INFO] Booting worker with pid: 19
[2017-03-30 23:40:23 +0000] [20] [INFO] Booting worker with pid: 20

Dies ist wahrscheinlich ein Fehler meinerseits und war nicht das gleiche Verhalten wie eines meiner Projektkollegen (mit einer ähnlichen, aber nicht identischen Codebasis in einer nahezu identischen AWS/CloudFormation/ALB/ECS-Bereitstellung). Ich dachte jedoch, ich würde es melden, falls es neue Einblicke in die Interaktionen zwischen ALB, ECS, Docker und gunicorn gibt.

Ich habe ein ähnliches Setup (convox mit ELB->ECS Docker Container->Gunicorn->Django) und kann bestätigen, dass die folgenden Konfigurationsänderungen anscheinend geholfen haben:

keepalive = 75 # needs to be longer than the ELB idle timeout
timeout = 90
worker_class = 'gevent'

Ich habe mein ELB-Idle-Timeout auf 60 Sekunden gesetzt.

Vor dem Ändern dieser Einstellungen habe ich die Standardeinstellungen für Keepalive, Timeout und den Sync-Worker verwendet.

Interessanterweise wurde diese Ausgabe am 10. April um 4 Uhr morgens UTC ausgestellt. Die App lief seit dem letzten Donnerstag ohne Änderungen einwandfrei.

nur stapeln, kein Docker, aber die bloße AWS-Instanz hatte das gleiche Problem hinter einem ELB. funktioniert NP auf osx, aber ubuntu16 mit einem ELB ist das gleiche Problem aufgetaucht. gevent Arbeiterklasse scheint es [für mich] zu beheben.

@erikcw scheint diese Lösung gefunden zu haben. Ich würde dieses Thema gerne schließen. Wenn jemand dies reproduzieren kann, nachdem das Gunicorn-Worker-Timeout und Keepalive-Timeout erhöht wurde, sagen Sie es bitte.

Verringern Sie alternativ das Leerlauf-Timeout für ELB.

Könnte nicht ein Client in freier Wildbahn (oder ein ruchloser Client) sich wie der ELB verhalten und das gleiche Problem verursachen?

@six8 ja. ELB schützt Sie auch nicht davor. Die Dokumentation behandelt dies: http://docs.gunicorn.org/en/latest/design.html#choosing -a-worker-type

Manche Leute kümmern sich nicht um diese Bedrohung und möchten Gunicorn einfach am Rand oder hinter einem ELB einsetzen. Das hier besprochene Problem sind Worker-Timeouts, die durch den ELB selbst verursacht werden. Ich möchte eine empfohlene Konfiguration bereitstellen, mit der Gunicorn hinter ELB mit Sync-Workern und ohne zusätzlichen Reverse-Proxy funktioniert.

Ich habe auch die Lösung von @erikcw ausprobiert,

CMD [ "gunicorn", "-k", "gevent", "--timeout", "10", "--keep-alive", "75", "--paste", "/etc/jzoo/app.ini" ]

Das hilft leider nicht:

[2017-07-04 08:36:23 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:24)
[2017-07-04 08:38:11 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:28)
[2017-07-04 08:39:39 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:29)
[2017-07-04 08:44:14 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:25)
[2017-07-04 08:44:55 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:31)

Ich habe eine Anwendung, die auf ECS hinter einer ALB mit Gunicorn-Synchronisierungsarbeitern ausgeführt wird. Ich habe noch kein Problem gesehen.

Kann jemand eine reproduzierbare Bereitstellung bereitstellen?

auch stapeln. dieses Problem bei der Verwendung von Kubernetes auf AWS mit ELB sehen. Zur Zeit arbeiten 8 Arbeiter. Per https://serverfault.com/questions/782022/keepalive-setting-for-gunicorn-behind-elb-ohne-nginx/ werden wir keepalive erhöhen und gemäß diesem Thread versuchen stattdessen gevent Arbeiter zu verwenden. Was jedoch im Moment fehlschlägt, sind einige Leistungstests für API-Aufrufe, die nicht selbst blockieren / Zeitüberschreitungen verursachen sollten. würde gerne wissen, was hier mit sync Arbeitern los ist. selbst wenn wir dies nach einigen der guten Richtlinien in diesem Thread zum Laufen bringen, hätten wir gerne etwas mehr Vertrauen in das, was vor der Bereitstellung in der Produktion vor sich geht.

Das Setzen der --worker-class auf --worker-class gevent hat bei mir funktioniert. Danke für die Kommentare und Hilfe!

@wichert das ist sehr seltsam. Mit dem gevent-Arbeiter sollten die Arbeitnehmer den Schiedsrichter auf einem separaten Greenlet von allen Verbindungen über ihre Lebensfähigkeit informieren. Ihre Keep-Alive-Einstellung sollte dies überhaupt nicht beeinflussen. Entweder stimmt etwas mit Ihrer Anwendung nicht, so dass gevent nicht wie vorgesehen funktioniert, oder etwas an der Einrichtung ist problematisch, das bei diesen anderen Szenarien auftreten kann.

Bitte stellen Sie allen in diesem Thread eine Anwendung zur Verfügung, die dieses Problem reproduziert. Ich habe es nicht reproduzieren können. Ohne Schritte zur Reproduktion bin ich versucht, zu schließen. Es gibt eine Mischung aus Empfehlungen und vielleicht sehr unterschiedlichen Themen, die in diesen Kommentaren verborgen sind. Es ist schwer zu wissen, was mit diesem Problem zu tun ist.

@tilgovi Ich habe dieses Problem erlebt, als ich die Worker-Klasse nicht für gevent angegeben habe (zB mit dem Standard-Sync-Worker). Mein Setup ist virtualenv mit pypy3 (PyPy 5.8.0-beta0), falcon 1.2 usw. (da Falcon nicht offiziell von pypy3 unterstützt wird). Ich habe den Cookiecutter von https://github.com/7ideas/cookiecutter-falcon verwendet und auf die neuesten Pakete aktualisiert. zB würde sich die Anfrage verzögern und dann würde ich den Fehler sehen; wenn ich die Anfrage nicht abbreche, würde sie schließlich antworten). Dies geschah nur mit der Standard-Worker-Klasse der Synchronisierung. Als ich die Verwendung von gevent angab, funktionierte alles.

Danke, @jhillhouse92 , ich werde es versuchen.

Ich sehe weiterhin Probleme mit Timeouts, @tilgovi. Ich werde morgen mehr Fehler beheben und ein Update mit genaueren Informationen veröffentlichen. Bitte halten Sie dieses Problem offen; Sie haben Recht, dass es eine Vielzahl von Problemen geben kann, aber das allgemeine Thema ist, dass Gunicorn-Worker (vielleicht nur mit der Sync-Worker-Klasse, tbd) Zeitüberschreitungsprobleme haben, wenn Gunicorn mit einer Anwendung verwendet wird, die mit AWS/ELB bereitgestellt wird. Hier stimmt etwas nicht, auch wenn wir das genaue Problem nicht isoliert haben. Es lohnt sich weiter zu graben. Ich werde morgen aktualisieren.

Bemerkenswert ist, dass ich dieses Problem lokal nicht in Docker/AWS/ELB mit dem oben erwähnten Stack erlebt habe.

Also verwende ich gevent, versuche meine Zugriffsprotokolle zu erfassen und versuche, meine App mit AWS/ELB bereitzustellen.

dockerfile-Befehle:

FROM cortex/base

CMD ["gunicorn", "-w", "8", "-b", "0.0.0.0:5000", "--capture-output", "--enable-stdio-inheritance", "--access-logfile", "-", "--worker-class", "gevent", "-t", "60", "--log-level", "debug", "app:app"]

Ich erhalte verrückte OOM-Fehler in Bezug auf Fehlercode 14, unabhängig davon, auf was ich die Grenzen setze. Hat das noch jemand im Zusammenhang mit diesem Problem gesehen? Zuvor konnte ich Worker-Timeouts sehen. Mit meinen aktuellen Konfigurationen kann ich die Timeouts nicht reproduzieren / so weit kommen.

[2017-07-19 18:27:39 +0000] [34] [ERROR] Exception in worker process
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/site-packages/gunicorn/arbiter.py", line 578, in spawn_worker
    worker.init_process()
  File "/usr/local/lib/python3.5/site-packages/gunicorn/workers/ggevent.py", line 190, in init_process
    super(GeventWorker, self).init_process()
  File "/usr/local/lib/python3.5/site-packages/gunicorn/workers/base.py", line 126, in init_process
    self.load_wsgi()
  File "/usr/local/lib/python3.5/site-packages/gunicorn/workers/base.py", line 135, in load_wsgi
    self.wsgi = self.app.wsgi()
  File "/usr/local/lib/python3.5/site-packages/gunicorn/app/base.py", line 67, in wsgi
    self.callable = self.load()
  File "/usr/local/lib/python3.5/site-packages/gunicorn/app/wsgiapp.py", line 65, in load
    return self.load_wsgiapp()
  File "/usr/local/lib/python3.5/site-packages/gunicorn/app/wsgiapp.py", line 52, in load_wsgiapp
    return util.import_app(self.app_uri)
  File "/usr/local/lib/python3.5/site-packages/gunicorn/util.py", line 376, in import_app
    __import__(module)
  File "/code/app/__init__.py", line 2, in <module>
    from flask_alchy import Alchy
  File "/usr/local/lib/python3.5/site-packages/flask_alchy.py", line 8, in <module>
    from flask_sqlalchemy import SQLAlchemy
  File "/usr/local/lib/python3.5/site-packages/flask_sqlalchemy/__init__.py", line 18, in <module>
    import sqlalchemy
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/__init__.py", line 9, in <module>
    from .sql import (
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/sql/__init__.py", line 8, in <module>
    from .expression import (
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/sql/expression.py", line 34, in <module>
    from .functions import func, modifier, FunctionElement, Function
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/sql/functions.py", line 11, in <module>
    from . import sqltypes, schema
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 658, in exec_module
  File "<frozen importlib._bootstrap_external>", line 763, in get_code
  File "<frozen importlib._bootstrap_external>", line 816, in get_data
OSError: [Errno 14] Bad address

Um es noch einmal zu wiederholen, ich sehe dies lokal ohne Docker nicht. Ich sehe dies lokal mit Docker nicht. Dies und Timeout-Probleme werden nur scheinbar im Docker/AWS/ELB-Stack (für mich) angezeigt.

@tilgovi Eine Sache, die ich anfangs falsch gemacht habe (wie in dem oben geposteten Snippet zu sehen ist), ist, dass ich das Timeout fälschlicherweise auf 10 Sekunden gesetzt hatte. Nachdem dies auf 75 Sekunden geändert wurde, sank die Anzahl der Worker-Timeouts erheblich auf vielleicht ein paar pro Tag. Der Vollständigkeit halber ist dies der genaue Befehl, den ich zum Starten unserer App verwende:

gunicorn -k gevent --timeout 90 --keep-alive 75 --paste /etc/jzoo/app.ini "$@"

Die .ini-Datei sieht so aus:

[DEFAULT]
sqlalchemy.url = postgresql://XXXX

[app:main]
use = egg:jzoo.api.admin

[server:main]
use = egg:gunicorn#main
bind = 0.0.0.0:5000
workers = 4
preload_app = true
loglevel = warning

# Logging configuration
[loggers]
keys = root,sqlalchemy,alembic,jzoo

# .. more logging configuration

Die Menge des Datenverkehrs scheint kein Faktor zu sein - ich sehe dies in unserer QA-Umgebung, in der nur sehr wenig Datenverkehr verzeichnet wird.

Wenn ich mir anschaue, wie oft dies passiert, frage ich mich, ob dies mit App-Neustarts zusammenhängen könnte.

ich habe ein etwas ähnliches Problem. Nach einigen Untersuchungen denke ich, dass es sich wahrscheinlich um einen Netzwerkverbindungsfehler handelt, nicht um einen von Gunicorn.

Hier ist mein Setup:

  • Der Postgresql-Server läuft auf Docker auf EC2. Das Docker-Image ist das offizielle Postgres 9.6.
  • Der App-Server wird auf Docker in einer VM außerhalb von EC2 ausgeführt. Das Docker-Image ist das offizielle Python 3.6.
  • In der AWS-Sicherheitsgruppe wird nur Port 5432 / tcp geöffnet.

Lustigerweise waren die meisten Anfragen vom App-Server an den Postgres-Server bis auf eine in Ordnung. Diese Abfrage scheint ewig zu laufen, wodurch der Gunicorn-Worker ein Timeout hat.

Das Problem ist weg, wenn ich die App lokal verwende.

Das Problem ist auch weg, wenn ich den App-Server nicht dockerisiere.

Meine temporäre Lösung ist, dass alle Verbindungen zwischen dem App-Server und dem Postgres-Server über die AWS-Sicherheitsgruppeneinstellung geöffnet werden. Jetzt funktioniert alles wieder richtig.

Ich vermute, dass es ein Verbindungsproblem zwischen dem Python-Container und AWS gibt. Ich werde aktualisieren, nachdem ich den AWS-Protokollstream gründlich untersucht habe.

Dankeschön!! Das Ändern des ELB- und Instanzprotokolls von HTTP auf TCP hat problemlos funktioniert 👍

Das Problem scheint nicht spezifisch für AWS zu sein, sondern für Docker selbst, wenn es mit Gunicorn kombiniert wird. Ich sehe dies auch bei gevent , zumindest in unserer Produktionsumgebung.

@tilgovi Hier ist eine einfache App, um diesen Fehler zu

app.py:

import falcon


class HelloResource:
    def on_get(self, req, resp):
        resp.media = {'info': 'hello world'}


app = falcon.API()
app.add_route('/', HelloResource())

Docker-Datei:

FROM python:3.6
WORKDIR /code
RUN pip install gunicorn falcon
COPY app.py .
CMD ["gunicorn", "app:app", "--bind", "0.0.0.0:8000"]

Ausführen: docker build -t gunicorn-and-docker . && docker run -p 8000:8000 -it --rm gunicorn-and-docker

Die Protokolle sehen so aus (zumindest für mich auf macOS Sierra mit Docker 17.06.2-ce-mac27 (19124)):

[2017-09-23 22:31:00 +0000] [1] [INFO] Starting gunicorn 19.7.1
[2017-09-23 22:31:00 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1)
[2017-09-23 22:31:00 +0000] [1] [INFO] Using worker: sync
[2017-09-23 22:31:00 +0000] [9] [INFO] Booting worker with pid: 9
[2017-09-23 23:22:45 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:9)
[2017-09-23 23:22:45 +0000] [9] [INFO] Worker exiting (pid: 9)
[2017-09-23 23:22:45 +0000] [11] [INFO] Booting worker with pid: 11
[2017-09-23 23:39:46 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:11)
[2017-09-23 23:39:46 +0000] [11] [INFO] Worker exiting (pid: 11)
[2017-09-23 23:39:46 +0000] [13] [INFO] Booting worker with pid: 13
[2017-09-23 23:41:10 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:13)
[2017-09-23 23:41:10 +0000] [13] [INFO] Worker exiting (pid: 13)
[2017-09-23 23:41:10 +0000] [15] [INFO] Booting worker with pid: 15
[2017-09-23 23:42:27 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:15)
[2017-09-23 23:42:27 +0000] [15] [INFO] Worker exiting (pid: 15)
[2017-09-23 23:42:27 +0000] [17] [INFO] Booting worker with pid: 17
[2017-09-23 23:43:44 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:17)
[2017-09-23 23:43:44 +0000] [17] [INFO] Worker exiting (pid: 17)
[2017-09-23 23:43:44 +0000] [19] [INFO] Booting worker with pid: 19
[2017-09-24 18:37:12 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:19)
[2017-09-24 18:37:12 +0000] [19] [INFO] Worker exiting (pid: 19)
[2017-09-24 18:37:12 +0000] [21] [INFO] Booting worker with pid: 21
[2017-09-24 19:49:20 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:21)
[2017-09-24 19:49:20 +0000] [21] [INFO] Worker exiting (pid: 21)
[2017-09-24 19:49:20 +0000] [23] [INFO] Booting worker with pid: 23
[2017-09-24 19:50:37 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:23)
[2017-09-24 19:50:37 +0000] [23] [INFO] Worker exiting (pid: 23)
[2017-09-24 19:50:37 +0000] [25] [INFO] Booting worker with pid: 25
[2017-09-24 20:25:48 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:25)
[2017-09-24 20:25:48 +0000] [25] [INFO] Worker exiting (pid: 25)
[2017-09-24 20:25:48 +0000] [27] [INFO] Booting worker with pid: 27

Hi,

Ich bin vor kurzem auf das gleiche Problem gestoßen.
In meinem Fall (ECS + gunicorn 19.7.1 + Django 1.11.5) habe ich es (anscheinend) geschafft, das Problem zu lösen, indem ich einfach den Speicher für den Container in der Aufgabendefinition erhöht habe (von 128 auf 256 MB).
Bisher keine Fehler mehr. Ich melde mich hier, wenn es wieder passiert.

Ergänze den Refrain hier noch ein wenig, aber das konnte ich nur lösen, indem ich auf gevent umschaltete.

Ich habe versucht, das Timeout auf 90 zu erhöhen und mit dem Sync-Worker auf 75 zu halten, ohne Erfolg.

Interessanterweise führt mein ELB in diesem Szenario nur die Weiterleitung auf TCP-Ebene und nicht HTTP durch.

Okay, ich habe einige Referenzen gefunden, die dies erklären. [1]

Es könnte mit kleinen Änderungen auf der Gunicorn-Seite gelöst werden. Wenn wir im Sync-Worker nach dem Akzeptieren einer neuen Verbindung select() mit einer kurzen Zeitüberschreitung aufgerufen haben, dann könnten wir diese Verbindungen verarbeiten. Vor allem bei mehreren Hörbuchsen könnte es etwas kompliziert werden. Am einfachsten wäre ein Timeout für das erste Byte. Ich bin mir auch nicht sicher, wie das mit SSL interagieren würde.

[1] https://cloudavail.com/2013/12/21/aws-elb-pre-open-connection-expose-part-1/

Wenn dies bei Ihnen der Fall ist und Sie gevent/eventlet/asyncio nicht verwenden möchten, empfehle ich, zum Thread-Worker zu wechseln (geben Sie die Einstellung --threads ).

@tilgovi Das Problem scheint auch bei gevent worker zu bestehen, wenn Sie sich mein Beispiel oben ansehen.

@jmagnusson Ihr Beispiel (aus diesem Kommentar: https://github.com/benoitc/gunicorn/issues/1194#issuecomment-331740187) scheint den Sync-Worker zu verwenden.

[2017-09-23 22:31:00 +0000] [1] [INFO] Arbeiter verwenden: sync

@tilgovi Stimmt, aber ich habe dies auch mit dem gevent Arbeiter in der Produktion erlebt. Ich werde versuchen, etwas Zeit zum Reproduzieren mit gevent zu finden.

Das mag nur ich sein (albern), aber in der EC2-Sicherheitsgruppe -> Inbound-Regeln habe ich eine benutzerdefinierte TCP-Regel für Port 5000 (gunicorn hier), um nur eine einzelne IP zuzulassen (meine IP: XX.XX.XX.XX /32), hilft es, dies auf alle IP zu ändern.

Ich treffe auch auf die Mühe.

[2018-01-02 16:38:03 +0800] [24355] [INFO] Starting gunicorn 19.7.1
[2018-01-02 16:38:03 +0800] [24355] [DEBUG] Arbiter booted
[2018-01-02 16:38:03 +0800] [24355] [INFO] Listening at: http://0.0.0.0:8080 (24355)
[2018-01-02 16:38:03 +0800] [24355] [INFO] Using worker: gevent
[2018-01-02 16:38:03 +0800] [24358] [INFO] Booting worker with pid: 24358
[2018-01-02 16:38:03 +0800] [24355] [DEBUG] 1 workers
[2018-01-02 16:38:03 +0800] [24358] [INFO] worker pid 24358 notify
[2018-01-02 16:38:04 +0800] [24358] [INFO] worker pid 24358 notify
[2018-01-02 16:38:05 +0800] [24358] [INFO] worker pid 24358 notify
[2018-01-02 16:38:06 +0800] [24358] [INFO] worker pid 24358 notify
[2018-01-02 16:38:07 +0800] [24358] [INFO] worker pid 24358 notify
[2018-01-02 16:38:08 +0800] [24358] [INFO] worker pid 24358 notify
[2018-01-02 16:38:09 +0800] [24358] [INFO] worker pid 24358 notify
[2018-01-02 16:38:10 +0800] [24358] [INFO] worker pid 24358 notify
[2018-01-02 16:38:10 +0800] [24358] [DEBUG] GET /v1/bj2/CC/uuid
[2018-01-02 16:38:10 +0800] [24358] [DEBUG] Closing connection. 
[2018-01-02 16:38:41 +0800] [24355] [CRITICAL] WORKER TIMEOUT (pid:24358)
[2018-01-02 16:38:41 +0800] [24358] [INFO] Worker exiting (pid: 24358)
[2018-01-02 16:38:41 +0800] [24381] [INFO] Booting worker with pid: 24381
[2018-01-02 16:38:41 +0800] [24381] [INFO] worker pid 24381 notify
[2018-01-02 16:38:42 +0800] [24381] [INFO] worker pid 24381 notify
[2018-01-02 16:38:43 +0800] [24381] [INFO] worker pid 24381 notify
[2018-01-02 16:38:44 +0800] [24381] [INFO] worker pid 24381 notify
[2018-01-02 16:38:45 +0800] [24381] [INFO] worker pid 24381 notify
[2018-01-02 16:38:46 +0800] [24381] [INFO] worker pid 24381 notify
[2018-01-02 16:38:47 +0800] [24381] [INFO] worker pid 24381 notify
......
[2018-01-02 16:48:20 +0800] [24381] [INFO] worker pid 24381 notify
[2018-01-02 16:48:51 +0800] [24355] [CRITICAL] WORKER TIMEOUT (pid:24381)
[2018-01-02 16:48:51 +0800] [24381] [INFO] Worker exiting (pid: 24381)
[2018-01-02 16:48:51 +0800] [24703] [INFO] Booting worker with pid: 24703
[2018-01-02 16:48:51 +0800] [24703] [INFO] worker pid 24703 notify
[2018-01-02 16:48:51 +0800] [24703] [DEBUG] GET /v1/bj2/CC/uuid
[2018-01-02 16:48:51 +0800] [24703] [DEBUG] Closing connection. 

Ich habe das Debug-Protokoll worker pid {WORKER_PID} notify hinzugefügt.

Laut Debug-Log ist

  1. Nur wenn der Worker-Prozess eine Anfrage erhält, wird die Benachrichtigung nicht fortgesetzt. Unabhängig davon, ob die Anforderungen vorliegen oder nicht, beendet der Master den Worker-Prozess nach 30 Sekunden.
  2. Nachdem die erste Anfrage geschlossen wurde, habe ich jetzt die zweite Anfrage gesendet, aber die zweite Anfrage ist blockiert und es gibt keine Antwort. Wenn das 30s-Timeout erreicht wurde, wurde der Worker-Prozess beendet und der neue Worker-Prozess antwortete auf die zweite Anforderung. Dann wurde der Server wieder aufgehängt.
  3. Wenn der Workerprozess aufgehängt wurde, würde er das Signal vom Master nicht empfangen, z. B. SIGTERM . Wenn das anmutige Timeout erreicht war, würde der Master es mit SIGKILL zwangsweise töten.
Python: 3.6.3
Gevent: 1.2.2
Gunicorn: 19.7.1
RUN CMD: gunicorn --worker-class gevent --log-level debug --bind 0.0.0.0:8080 app

HINWEIS: Wenn ich eventlet als Arbeiter verwende, ist es in Ordnung.

Ich schließe dieses Thema, da ich es für veraltet halte. Soweit ich feststellen kann, ist das beobachtete Verhalten darauf zurückzuführen, dass AWS Classic Load Balancer eine Pre-Open-Optimierung durchführt. Diese Optimierung wird nur von Classic Load Balancern durchgeführt, gemäß der Dokumentation zur Funktionsweise des Load Balancing . Der Wechsel zu Application Load Balancer sollte das Problem beheben. Darüber hinaus ist es, wie in diesem Blogbeitrag dokumentiert, möglich, AWS aufzufordern, die Pre-Open-Optimierung zu deaktivieren oder das Worker-Timeout für Gunicorn zu erhöhen.

@tilgovi FWIW Ich habe das mit ALB gesehen. Ich habe noch nie klassische Load Balancer verwendet.

@tilgovi Auch ich habe dies wiederholt in ALB-only-Umgebungen beobachtet, ohne Classic verwendet zu haben. Auch mit Anpassungen der Worker-Timeouts haben wir dies weiterhin gesehen.

@tilgovi Ich

Jemand muss dann helfen, dies zu reproduzieren, und versuchen, es zu debuggen. Ich kann es nicht mit ALB reproduzieren und ich kann nicht sehen, wie ich es außerhalb von AWS reproduzieren kann.

@xgfone Vielleicht möchten Sie Ihre eigene Ausgabe öffnen, der Titel dieser Ausgabe ist "docker + AWS"

Hat das jemand mit den AWS-Load-Balancern erlebt, aber ohne Docker? Ich bin etwas verwirrt, muss ich zugeben :)

Mein Eindruck war, dass das Problem wirklich mehr mit Docker zu tun hatte - zumindest hatte ich genau die gleichen Probleme beim Ausführen mehrerer gunicorn Sync-Worker in Docker auf meinem lokalen Computer.

Diese Konfiguration funktionierte ohne Docker auf Ubuntu- und RHEL-Maschinen, sowohl Bare Metal als auch virtualisiert in Digital Ocean:

workers = 2
worker_class = 'sync'
worker_connections = 1000
timeout = 30
keepalive = 2

Innerhalb von Docker (auch RHEL, alles andere gleich) liefen die Worker immer in Timeout und starteten permanent neu. Ich habe die Empfehlungen aus diesem Thread übernommen und zu diesem gewechselt, was perfekt funktioniert:

workers = 1
threads = 8
worker_class = 'sync'
worker_connections = 1000
timeout = 30
keepalive = 2

Wenn du denkst, dass dies nichts mit diesem Thread zu tun hat, entferne ich es gerne von hier und stelle es woanders hin ;-)

Beste, Boris

@tilgovi

Dieser Fehler tritt in arbiter.py, murder_workers . Die Funktion murder_workers wird aufgerufen, wenn SIG_QUEUE leer ist (zB beim Warten auf Signale).

Es würde dann jede Sekunde prüfen, ob das Timeout erreicht wurde. Die verbleibende Lebenszeit betrug immer 1 Sek. oder 0 Sek., da sich der Gevent-Worker in einer kontrollierten Endlosschleife befindet, während self.alive self.notify aufgerufen hat, das eine Datei aktualisiert. Mit den Aktualisierungen der Datei überprüft gunicorn, wann die letzte aktive Zeit aufgetreten ist.

Die einzige Möglichkeit, wie die Funktion "Time to live check" in der murder_workers Funktion fehlschlägt (z. B. sagt, dass sie zu lange inaktiv war), besteht darin, dass die Eigenschaft "gevent alive" geändert wurde. Die folgenden Methoden steuern dies:

handle_quit
handle_request (wenn maximale Anfragen empfangen wurden, sind dies standardmäßig 2^64 Bit der Anzahl der Anfragen oder 2^32 bei 32-Bit-Betriebssystemen)
changed (wird vom Reloader aufgerufen, wenn eine Datei geändert wurde)
handle_exit
handle_abort

Diese Methoden werden von Signalen aufgerufen

handle_quit - SIGQUIT, SIGINT
handle_exit - SIGTERM
handle_abort - SIGABRT

Daher sehe ich 2 mögliche Probleme:

  1. Die Methode Benachrichtigung kann die Datei während ihrer Schleife nicht aktualisieren
  2. Ein Signal wird falsch gesendet

Ich denke, die wahrscheinlichere Ursache ist die 2. Die Hauptquelle der Signale befindet sich in der Arbiter-Datei und wird durch diese Ausnahmen ausgelöst:

  • StopIteration
  • KeyboardInterrupt
  • HaltServer
  • Exception (unbehandelte Ausnahme)

Ich denke, die StopIteration-Ausnahme ist höchstwahrscheinlich der Übeltäter, der in der Datei async.py bei req = six.next(parser) ausgelöst wurde. Es scheint, dass diese nächste Methode nur parser.next() aufruft.

Parser.next() löst eine StopIteration Ausnahme unter den folgenden 2 Bedingungen aus:

1. If the message indicates it should close:
    1. http Connection close (and keep-alive false)
    2. WSGI - request method not HEAD, response_length is none, and status code is > 200 (but not 204, or 304)
2. If self.mesg (Request message) is falsey

Ich bin mir nicht sicher, was genau das unbeabsichtigt verursachen könnte, aber von 62 Kommentaren, bei denen dieses Problem in mehreren Apps und Umgebungen aufgetreten ist, denke ich, dass dies eine weitere Untersuchung wert ist, und empfehle, es erneut zu öffnen oder wenn uns der Titel nicht gefällt , schaffen ein neues globales Problem mit kritischen Zeitüberschreitungen der Arbeitnehmer.

Ich werde dies erneut öffnen und versuchen, diese Kombinationen zu testen:

  • Docker lokal
  • Docker AWS mit Classic Load Balancer
  • Docker AWS mit Application Load Balancer

Wenn jemand ein Repo erstellen möchte, das dies reproduzieren kann, wäre das hilfreich, aber ich kann es wahrscheinlich dieses Wochenende tun.

Ich habe dieses Problem und verwende AWS nicht.
Mein Setup ist NGINX -> Docker Container (Gunicorn mit gevent Arbeitern + Django). Ich verwende die Standard-Timeouts des Gunicorn.

Irgendwelche Tipps?

Vielen Dank.

Hallo @davidmir ,
Ich hatte das gleiche Problem, das Ändern des Worker-Typs hat nicht geholfen. Der Wechsel zu einem einzelnen Sync-Worker mit mehreren Threads hat für mich den Trick gemacht:

workers = 1
threads = 8
worker_class = 'sync'
worker_connections = 1000
timeout = 30
keepalive = 2

Beste, Boris

Obwohl oben einige erwähnt wurden, sind einige von diesen Fehlern aufgrund meines eigenen Debuggings dieses Problems; vor allem, wenn es behoben wird, indem der Arbeiter-Countdown auf 1 geändert wird.

Dies ist bei Docker besonders problematisch, wenn Sie so etwas in Ihrer Konfiguration haben:

workers = multiprocessing.cpu_count() * 2 + 1

Begrenzen jedoch den für den Container verfügbaren Speicher; Der synchrone Worker startet mehrere potenziell schwergewichtige Python-Interpreter. Beachten Sie, dass die CPU-Anzahl auf der Gesamt-CPU-Anzahl des Computers basiert und nicht auf dem, was Sie für den Docker-Container bereitgestellt haben. Wenn Sie einen begrenzten Container ausführen, sollten Sie die Anzahl der Worker stattdessen darauf stützen.

Obwohl es von Anwendung zu Anwendung unterschiedlich ist, lautet meine Faustregel 256 MB pro Arbeiter in einer schlanken Konfiguration und 512, um sicher zu gehen.

Hatte das gleiche Problem mit Classic ELB HTTPS => HTTP Gunicorn Sync Workers

Wie andere bereits erwähnt haben, bestand die einfachste Lösung darin, das Argument -k gevent anstelle des Standard-Sync-Workers zu verwenden.

Wir haben gesehen, dass das gleiche Problem bei einem völlig neuen Docker-Container (der in ECS hinter ALB gehostet wird) erneut auftauchte und eine völlig andere (aber im Nachhinein offensichtliche) Lösung gefunden haben: dem Container in CloudFormation mehr Speicher zuweisen Vorlage.

Wir litten letztes Jahr unter diesem Problem und fanden nie eine Ursache für die rauchende Waffe, aber heute Abend entdeckte ich es auf einem neuen Container und bemerkte zufällig, dass der Container den gesamten Speicher auffrisst, den wir zugewiesen hatten. Sobald ich die Zuweisung verdoppelt habe, haben die Container diesen Fehler nicht mehr ausgegeben (noch bevor ich mehr zugewiesen habe, als es letztendlich verbrauchen würde):
https://github.com/hackoregon/civic-devops/issues/157

Stehe hier vor einem ähnlichen Problem. der Code ist so einfach wie

while true:
      sleep(10)

kann dazu führen, dass Arbeiter sterben (ohne diesen Code ist unsere Bereitstellung normal)
es ist sehr rätselhaft, b/c sleep sollte schon einen Herzschlag senden.

habe auch schon auf gevent gewechselt, hat nicht geholfen. Frage mich, ob jemand eine Idee hat?

Beispielausgabe:
[2018-06-16 16:00:16 +0000] [136] [CRITICAL] WORKER TIMEOUT (pid:521) [2018-06-16 16:00:16 +0000] [136] [CRITICAL] WORKER TIMEOUT (pid:522) [2018-06-16 16:00:16 +0000] [136] [CRITICAL] WORKER TIMEOUT (pid:523) [2018-06-16 16:00:16 +0000] [136] [CRITICAL] WORKER TIMEOUT (pid:524) [2018-06-16 16:00:16 +0000] [136] [CRITICAL] WORKER TIMEOUT (pid:525) [2018-06-16 16:00:16 +0000] [524] [INFO] Worker exiting (pid: 524) [2018-06-16 16:00:16 +0000] [521] [INFO] Worker exiting (pid: 521) [2018-06-16 16:00:16 +0000] [523] [INFO] Worker exiting (pid: 523) [2018-06-16 16:00:16 +0000] [522] [INFO] Worker exiting (pid: 522) [2018-06-16 16:00:16 +0000] [525] [INFO] Worker exiting (pid: 525) [2018-06-16 16:00:17 +0000] [531] [INFO] Booting worker with pid: 531 /usr/local/lib/python3.6/site-packages/gunicorn/workers/ggevent.py:65: MonkeyPatchWarning: Monkey-patching ssl after ssl has already been imported may lead to errors, including RecursionError on Python 3.6. Please monkey-patch earlier. See https://github.com/gevent/gevent/issues/1016 monkey.patch_all(subprocess=True) [2018-06-16 16:00:17 +0000] [136] [DEBUG] 1 workers [2018-06-16 16:00:17 +0000] [532] [INFO] Booting worker with pid: 532 [2018-06-16 16:00:17 +0000] [533] [INFO] Booting worker with pid: 533 /usr/local/lib/python3.6/site-packages/gunicorn/workers/ggevent.py:65: MonkeyPatchWarning: Monkey-patching ssl after ssl has already been imported may lead to errors, including RecursionError on Python 3.6. Please monkey-patch earlier. See https://github.com/gevent/gevent/issues/1016 monkey.patch_all(subprocess=True) [2018-06-16 16:00:17 +0000] [534] [INFO] Booting worker with pid: 534 /usr/local/lib/python3.6/site-packages/gunicorn/workers/ggevent.py:65: MonkeyPatchWarning: Monkey-patching ssl after ssl has already been imported may lead to errors, including RecursionError on Python 3.6. Please monkey-patch earlier. See https://github.com/gevent/gevent/issues/1016 monkey.patch_all(subprocess=True) [2018-06-16 16:00:17 +0000] [535] [INFO] Booting worker with pid: 535 [2018-06-16 16:00:17 +0000] [136] [DEBUG] 5 workers

Es tut mir leid, dass ich hier das Wasser trübe, aber ich wollte nur meine Erfahrung teilen, mein Stack ist HTTP ELB > Nginx > gunicorn/gevent on EC2 , Prozesse laufen mit circusd

Das Problem, das ich festgestellt habe, war, dass nach der Instrumentierung meiner Django-App mit elastischem-apm meine HTTP-Gesundheitsprüfungen fast sofort fehlschlagen und gunicorn nach einigen Sekunden nicht mehr reagiert.

Ich habe ein paar lokale wrk Benchmarks gegen meinen Gesundheitscheck ausprobiert, die Synchronisierung hat für 1-5 Arbeiter etwa 300 RPS erhalten, aber Gevent würde 1 R / s erhalten. Das Ausschalten von apm brachte Gevent auf etwa 50 Rps und einen vernachlässigbaren Anstieg für die Synchronisierung.

Ich habe keine seltsame Speichernutzung bei Valgrind bemerkt, normalerweise etwa 4 MB für Gunicorn und 40 MB pro Arbeiter

Wie auch immer, das Aktualisieren von gunicorn 19.6.0 > 19.9.0 und gevent 1.2.2 > 1.3.6 gibt mir wieder einen stabilen ELB-Gesundheitscheck und ~300 RPS lokal. Ich hatte Gunicorn / Gevent absichtlich nicht aktualisiert, bis ich etwas APM-Login hatte, scheint dies zu einem gewissen Glücksfall zu führen. Die Aktualisierung von Gevent gab verständlicherweise den größten Schub, aber dann schien die Aktualisierung von Gunicorn weitere 10 % oder so hinzuzufügen.

Haben Sie sich die Changelogs noch nicht im Detail angeschaut, vielleicht können die Betreuer die wahrscheinlichste Ursache aufklären?

Wie auch immer, das Aktualisieren von gunicorn 19.6.0 > 19.9.0 und gevent 1.2.2 > 1.3.6 gibt mir wieder einen stabilen ELB-Gesundheitscheck und ~300 RPS lokal .... Das Aktualisieren von gevent gab den größten Schub

Wow, das ist ziemlich cool!

Thema schließen. seit einiger Zeit keine Aktivität mehr.

FWIW, ich habe dieses Problem immer noch @benoitc :-\

Django 2.1.5
Gunicorn 19.8.1
gevent 1.2.2
AKS 1.15.7 mit 5 Nodes (Standard B2's - 2 vcores und 2GB Speicher)
3 Pods/Docker-Container mit jeweils:

    spec:
      containers:
        - name: web-container
          command: ["newrelic-admin"]
          args: [
              "run-program",
              "gunicorn",
              "--limit-request-field_size=16380", # limit also specified in nginx
              "--workers=3", # (2 x vcpu) + 1. vcpu < limit defined in resources
              "-k=gevent",
              "-b=0.0.0.0:8000",
              "ourapp.wsgi",
              "--timeout 60",
              "--log-level=debug",
            ]
          resources:
            requests:
              memory: "200Mi"
              cpu: "250m"
            limits:
              memory: "3000Mi"
              cpu: "2000m"

Gleiches Problem hier mit EKS, Nginx und einer NLB.

@salmicrosoft @sinkr OK, aber bitte eröffnen Sie ein neues Problem und stellen Sie alle Protokolle bereit, die uns helfen könnten, herauszufinden, was passiert. Und was macht deine App? Haben Sie eine lange Anfrage?

Ich hatte das gleiche Problem auf dem ECS Fargate, aber es hing mit falschen Keepalive/Timeout-Einstellungen in Docker/gunicorn.conf.py zusammen
Keepalive (nicht gesetzt)
Zeitüberschreitung=2

Vor der Behebung funktioniert es gut mit einem lokal ausgeführten Container, ist aber auf dem ECS Fargate fehlgeschlagen, jetzt funktioniert es in beiden Umgebungen korrekt.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen