Ich versuche, Gunicorn auf Docker einzurichten. Es funktioniert lokal gut und das Produktions-Image ist genau das gleiche wie das lokale Image, aber ich erhalte dieses seltsame Verhalten bei der Docker-Produktions-Engine:
ml-server_1 | [2017-12-11 13:18:50 +0000] [1] [INFO] Starting gunicorn 19.7.1
ml-server_1 | [2017-12-11 13:18:50 +0000] [1] [DEBUG] Arbiter booted
ml-server_1 | [2017-12-11 13:18:50 +0000] [1] [INFO] Listening at: http://0.0.0.0:80 (1)
ml-server_1 | [2017-12-11 13:18:50 +0000] [1] [INFO] Using worker: sync
ml-server_1 | [2017-12-11 13:18:50 +0000] [8] [INFO] Booting worker with pid: 8
ml-server_1 | [2017-12-11 13:18:50 +0000] [1] [DEBUG] 1 workers
ml-server_1 | Using TensorFlow backend.
ml-server_1 | [2017-12-11 13:18:54 +0000] [11] [INFO] Booting worker with pid: 11
ml-server_1 | Using TensorFlow backend.
ml-server_1 | [2017-12-11 13:18:58 +0000] [14] [INFO] Booting worker with pid: 14
ml-server_1 | Using TensorFlow backend.
ml-server_1 | [2017-12-11 13:19:02 +0000] [17] [INFO] Booting worker with pid: 17
ml-server_1 | Using TensorFlow backend.
Es sieht so aus, als ob gunicorn alle 4-5 Sekunden Arbeiter bootet, obwohl keine Fehlermeldungen oder Exit-Signale erkennbar sind. Dieses Verhalten wird auf unbestimmte Zeit fortgesetzt, bis es beendet wird.
Ist es möglich, dass ein Arbeiter aussteigen kann, ohne etwas in stderr/stdout zu protokollieren, oder dass der Arbiter unendlich viele Arbeiter hervorbringt?
Da es sich um dasselbe Docker-Image handelt, fĂŒhren sie genau denselben Code auf genau derselben Architektur aus, daher bin ich wirklich verwirrt, was das sein könnte (Fehler?). Jede Hilfe wird sehr geschĂ€tzt!
ssh
-ing in den Docker-Container fĂŒhrte mich zu diesem Fehler:
Illegal instruction (core dumped)
Vielleicht sollte gunicorn solche Fehler an die OberflĂ€che bringen, anstatt sie zu schlucken, oder anders damit umgehen? Ich bin mir nicht sicher, dachte nur, ich wĂŒrde das ansprechen, da es jemand anderem helfen könnte!
Danke fĂŒr die Meldung des Problems!
Wenn Sie herausfinden können, wo dies geschieht, wÀre das sehr hilfreich.
Vielleicht können wir die Protokollierung hinzufĂŒgen, wenn die Arbeiter das Unternehmen verlassen. Normalerweise loggt sich der Arbeiter selbst ein, aber wenn er sehr abrupt getötet wird, tut er das nicht.
Kein Problem!
Es scheint ein Problem mit Spacy zu geben, das ich gerade zu diesem Thread hinzugefĂŒgt habe: https://github.com/explosion/spaCy/issues/1589
Wie auch immer, es verursacht ein SIGILL
wie strace
bestÀtigt:
--- SIGILL {si_signo=SIGILL, si_code=ILL_ILLOPN, si_addr=0x7ff48bbe6cea} ---
+++ killed by SIGILL (core dumped) +++
Illegal instruction (core dumped)
Ich nehme an, es wĂ€re schön, wenn gunicorn dies identifizieren und einen Fehler protokollieren könnte, anstatt den Worker gespenstisch neu zu starten, aber ich weiĂ sehr wenig darĂŒber, wie Exit-Codes funktionieren!
Einige Exit-Codes haben definitiv besondere Bedeutungen und wir könnten diese wahrscheinlich protokollieren.
http://tldp.org/LDP/abs/html/exitcodes.html
Hört sich gut an! Wenn der Exit-Code kein reservierter Exit-Code ist (wie in diesem Fall), wĂ€re es auĂerdem cool, wenn dies (ohne ErklĂ€rung) protokolliert werden könnte, damit es offensichtlich ist, dass der Worker tatsĂ€chlich beendet đ
Ich habe ein Ă€hnliches Problem, Gunicorn bootet immer einen neuen Arbeiter, wenn ich eine HTTP-Anfrage stelle. Ich bekomme keine Antwort zurĂŒck, es startet nur immer ein neuer Arbeiter neu. Strace-Log von zwei http-Anfragen:
select(4, [3], [], [], {1, 0}) = 0 (Timeout)
fstat(6, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0}) = ? ERESTARTNOHAND (To be restarted if no handler)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED, si_pid=510, si_uid=0, si_status=SIGSEGV, si_utime=160, si_stime=32} ---
getpid() = 495
rt_sigreturn({mask=[]}) = -1 EINTR (Interrupted system call)
wait4(-1, [{WIFSIGNALED(s) && WTERMSIG(s) == SIGSEGV && WCOREDUMP(s)}], WNOHANG, NULL) = 510
lseek(8, 0, SEEK_CUR) = 0
close(8) = 0
wait4(-1, 0x7ffd455ad844, WNOHANG, NULL) = 0
write(4, ".", 1) = 1
select(4, [3], [], [], {0, 840340}) = 1 (in [3], left {0, 840338})
read(3, ".", 1) = 1
read(3, 0x7f2682025fa0, 1) = -1 EAGAIN (Resource temporarily unavailable)
fstat(6, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG, st_size=0, ...}) = 0
umask(0) = 022
getpid() = 495
open("/tmp/wgunicorn-q4aa72u7", O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_CLOEXEC, 0600) = 8
fcntl(8, F_SETFD, FD_CLOEXEC) = 0
chown("/tmp/wgunicorn-q4aa72u7", 0, 0) = 0
umask(022) = 0
unlink("/tmp/wgunicorn-q4aa72u7") = 0
fstat(8, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
ioctl(8, TIOCGWINSZ, 0x7ffd455b8e50) = -1 ENOTTY (Not a tty)
lseek(8, 0, SEEK_CUR) = 0
lseek(8, 0, SEEK_CUR) = 0
rt_sigprocmask(SIG_BLOCK, ~[], [], 8) = 0
fork() = 558
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
select(0, NULL, NULL, NULL, {0, 37381}[2017-12-28 17:50:23 +0000] [558] [INFO] Booting worker with pid: 558
) = 0 (Timeout)
select(4, [3], [], [], {1, 0}loading test-eu-ovh settings
) = 0 (Timeout)
fstat(6, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0}
) = 0 (Timeout)
fstat(6, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0}) = 0 (Timeout)
fstat(6, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0}) = 0 (Timeout)
fstat(6, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0}) = 0 (Timeout)
fstat(6, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0}) = 0 (Timeout)
fstat(6, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0}) = 0 (Timeout)
fstat(6, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG, st_size=0, ...}) = 0
select(4, [3], [], [], {1, 0}) = ? ERESTARTNOHAND (To be restarted if no handler)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED, si_pid=499, si_uid=0, si_status=SIGSEGV, si_utime=160, si_stime=31} ---
getpid() = 495
rt_sigreturn({mask=[]}) = -1 EINTR (Interrupted system call)
wait4(-1, [{WIFSIGNALED(s) && WTERMSIG(s) == SIGSEGV && WCOREDUMP(s)}], WNOHANG, NULL) = 499
lseek(7, 0, SEEK_CUR) = 0
close(7) = 0
wait4(-1, 0x7ffd455ad844, WNOHANG, NULL) = 0
write(4, ".", 1) = 1
select(4, [3], [], [], {0, 450691}) = 1 (in [3], left {0, 450689})
read(3, ".", 1) = 1
read(3, 0x7f2682067de8, 1) = -1 EAGAIN (Resource temporarily unavailable)
fstat(6, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG, st_size=0, ...}) = 0
umask(0) = 022
getpid() = 495
open("/tmp/wgunicorn-5x9a40ca", O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_CLOEXEC, 0600) = 7
fcntl(7, F_SETFD, FD_CLOEXEC) = 0
chown("/tmp/wgunicorn-5x9a40ca", 0, 0) = 0
umask(022) = 0
unlink("/tmp/wgunicorn-5x9a40ca") = 0
fstat(7, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
ioctl(7, TIOCGWINSZ, 0x7ffd455b8e50) = -1 ENOTTY (Not a tty)
lseek(7, 0, SEEK_CUR) = 0
lseek(7, 0, SEEK_CUR) = 0
rt_sigprocmask(SIG_BLOCK, ~[], [], 8) = 0
fork() = 579
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
select(0, NULL, NULL, NULL, {0, 8144}[2017-12-28 17:50:30 +0000] [579] [INFO] Booting worker with pid: 579
) = 0 (Timeout)
select(4, [3], [], [], {1, 0}) = 0 (Timeout)
fstat(6, {st_mode=S_IFREG, st_size=0, ...}) = 0
fstat(7, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
fstat(9, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
fstat(8, {st_mode=S_IFREG|01, st_size=0, ...}) = 0
Ich stehe vor dem gleichen Problem, gunicorn
bootet innerhalb von Sekunden fĂŒr den Arbeitertyp sync
. Das Setzen des Worker-Timeouts auf 900
hilft nicht.
In meinem Ladevorgang vor der Aktion lade ich Daten von AWS S3 herunter. Das Herunterladen der verschiedenen Dateien dauert ca. 1 Min. 10 Sek.
@sara-02 Was ist Ihre Befehlszeile, um Gunicorn zu starten?
@benoitc gunicorn --pythonpath /src -b 0.0.0.0:$SERVICE_PORT --workers=1 -k sync -t $SERVICE_TIMEOUT flask_endpoint:app
Hier prÀsentieren
@sara-02 Danke.
Steigen alte Arbeiter wirklich aus oder werden sie online gehalten und neue Arbeiter werden hervorgebracht? Was zeigt das Debug-Log auch?
Die Logs werden mit Botocore-Logs gemischt, aber es ist ungefĂ€hr so ââââ
[INFO] Booting worker with pid: a
[INFO] Booting worker with pid: b
[INFO] Booting worker with pid: c
aber werden die Arbeiter getötet? Was gibt den Befehl ps ax|grep gunicorn
?
@benoitc
Eine Frage jedoch, warum sehen wir 2 gunicorn
Prozesse, wenn das Worker-Limit auf 1 gesetzt ist? Ist ein Meister und ein Arbeiter?
Es gibt 1 Arbiter-Prozess (Master) und N Worker-Prozesse ihr :)
Sie fĂŒhren den Befehl also jedes Mal aus, wenn ein Worker gebootet hat, oder? Wenn dies der Fall ist, scheint der Ă€ltere Arbeiter getötet zu werden, und ein neuer wird gespawnt. Ich werde ermitteln.
@sara-02 eine letzte Sache, dies geschieht auch im Docker?
@benoitc auf docker-compose
funktioniert wie erwartet, aber wenn ich den gleichen Code auf Openshift
setze , sehe ich diesen Fehler. Das Erhöhen des Speicherbedarfs wurde behoben, aber wenn ich die Anwendung ĂŒber docker-compose
ausfĂŒhre, limited
Speicher.
Nur ein Update, das Problem war fĂŒr mich eigentlich ein Speicherfehler und wurde behoben, als das Speicherproblem behoben wurde.
@benoitc
Ich stehe vor dem gleichen Problem, als ich versuche, 5 Gunicorn-Arbeiter im Docker zu spawnen.
@sara-02
Wie haben Sie die Ursache fĂŒr einen Speicherfehler identifiziert?
@gulshan-gaurav 2 Dinge haben mir geholfen:
Ich habe den meinem Pod zugewiesenen Speicher erhöht und stĂŒrzte nicht mehr ab. Zweitens haben wir unsere Openshift Zabbix-Protokolle ĂŒberprĂŒft.
@sara-02
Selbst auf meinem Staging-Pod betragen die Dateien + Modelle, die ich in den Speicher lade, 50 MB, sodass 2 GB Speicher fĂŒr 5 Mitarbeiter ausreichen sollten.
@gulshan-gaurav Welches Problem hast du? Es sieht gut aus, 5 Prozesse zu haben....
Ich hatte das gleiche Problem. Ich habe das genaue Problem nicht gefunden, aber es wurde gelöst, als ich von Python 3.5 auf 3.6 aktualisiert habe.
Ich habe das gleiche Problem in einem Docker-Container. Gunicorn setzt jedes Mal, wenn ich einen Endpunkt aufrufe, der den Fehler verursacht, aber keine Ausnahme oder Fehler in den Protokolldateien von Gunicorn ausgegeben wird, einen neuen Worker an. Dinge, die ich zum Drucken auswÀhle, werden protokolliert und plötzlich sagt die Protokolldatei nur "Booting worker with pid..."
Ein hilfreicher Schritt war das HinzufĂŒgen der env-Variablen PYTHONUNBUFFERED. Davor wĂŒrden sogar die Druckanweisungen verschwinden und nicht in den Protokollen von Gunicorn gespeichert werden.
2 andere Endpunkte der App funktionieren ordnungsgemĂ€Ă.
Ich betreibe Gunicorn mit: gunicorn run:app -b localhost:5000 --enable-stdio-inheritance --error-logfile /var/log/gunicorn/error.log --access-logfile /var/log/gunicorn/access. log --capture-output --log-level debug
Ich habe bereits Python 3.6 ausgefĂŒhrt und mit top ĂŒberprĂŒft, dass der Speicher kein Problem zu sein scheint.
BEARBEITEN: Es sieht so aus, als ob es ein Python-Problem war und nicht die Schuld von Gunicorn. Einige Versionsdiskrepanzen fĂŒhrten dazu, dass Python einfach spurlos starb, wĂ€hrend eine bestimmte Operation ausgefĂŒhrt wurde.
Ich stehe vor einem Àhnlichen Problem, bei dem der Worker-Knoten immer wieder auftaucht
Booting worker with pid: 17636
. Ich weià nicht, ob es den vorherigen Worker-Knoten tötet oder der vorherige Worker-Knoten noch existiert. Aber die Anzahl der Arbeiter, die in den Befehlszeilenargumenten von gunicorn erwÀhnt werden, betrÀgt nur 3 - -workers=3
. AuĂerdem verwende ich Python-Version 3.7
Ich hatte ein MissverhÀltnis von scikit-learn-AbhÀngigkeit, aber selbst nachdem ich das gelöst habe, kommen immer noch die gleichen unendlichen Arbeiter auf mich zu. Auf welche Art von Python-Versionsdiskrepanzen sollte ich achten und wie kann ich sie identifizieren?
Ich stehe vor dem gleichen Problem in OpenShift.
Wie Sie im Bild sehen können, verwende ich 6 Arbeiter (ich habe es mit 3 versucht).
Ich habe den Speicher des Pods erhöht und es funktioniert nicht.
BuildConfig:
Irgendeine Idee?
Vielen Dank
LÀufst du das in aws hinter elb? Ich habe dieses Problem gelöst, indem ich Nginx-Ingress zwischen Elb und Gunicorn platziert habe
Habe das gleiche Problem.
flask_1 | [2019-02-23 09:08:17 +0000] [1] [INFO] Starting gunicorn 19.9.0
flask_1 | [2019-02-23 09:08:17 +0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)
flask_1 | [2019-02-23 09:08:17 +0000] [1] [INFO] Using worker: sync
flask_1 | [2019-02-23 09:08:17 +0000] [8] [INFO] Booting worker with pid: 8
flask_1 | [2019-02-23 09:08:19 +0000] [12] [INFO] Booting worker with pid: 12
flask_1 | [2019-02-23 09:08:19 +0000] [16] [INFO] Booting worker with pid: 16
flask_1 | [2019-02-23 09:08:20 +0000] [20] [INFO] Booting worker with pid: 20
flask_1 | [2019-02-23 09:08:21 +0000] [24] [INFO] Booting worker with pid: 24
flask_1 | [2019-02-23 09:08:22 +0000] [28] [INFO] Booting worker with pid: 28
flask_1 | [2019-02-23 09:08:23 +0000] [32] [INFO] Booting worker with pid: 32
flask_1 | [2019-02-23 09:08:25 +0000] [36] [INFO] Booting worker with pid: 36
flask_1 | [2019-02-23 09:08:26 +0000] [40] [INFO] Booting worker with pid: 40
flask_1 | [2019-02-23 09:08:27 +0000] [44] [INFO] Booting worker with pid: 44
flask_1 | [2019-02-23 09:08:29 +0000] [48] [INFO] Booting worker with pid: 48
flask_1 | [2019-02-23 09:08:30 +0000] [52] [INFO] Booting worker with pid: 52
flask_1 | [2019-02-23 09:08:31 +0000] [56] [INFO] Booting worker with pid: 56
flask_1 | [2019-02-23 09:08:33 +0000] [60] [INFO] Booting worker with pid: 60
flask_1 | [2019-02-23 09:08:34 +0000] [64] [INFO] Booting worker with pid: 64
flask_1 | [2019-02-23 09:08:35 +0000] [68] [INFO] Booting worker with pid: 68
flask_1 | [2019-02-23 09:08:36 +0000] [72] [INFO] Booting worker with pid: 72
flask_1 | [2019-02-23 09:08:37 +0000] [76] [INFO] Booting worker with pid: 76
flask_1 | [2019-02-23 09:08:38 +0000] [80] [INFO] Booting worker with pid: 80
flask_1 | [2019-02-23 09:08:40 +0000] [84] [INFO] Booting worker with pid: 84
flask_1 | [2019-02-23 09:08:41 +0000] [88] [INFO] Booting worker with pid: 88
flask_1 | [2019-02-23 09:08:42 +0000] [92] [INFO] Booting worker with pid: 92
flask_1 | [2019-02-23 09:08:44 +0000] [96] [INFO] Booting worker with pid: 96
flask_1 | [2019-02-23 09:08:45 +0000] [100] [INFO] Booting worker with pid: 100
flask_1 | [2019-02-23 09:08:45 +0000] [104] [INFO] Booting worker with pid: 104
flask_1 | [2019-02-23 09:08:46 +0000] [108] [INFO] Booting worker with pid: 108
flask_1 | [2019-02-23 09:08:47 +0000] [112] [INFO] Booting worker with pid: 112
flask_1 | [2019-02-23 09:08:48 +0000] [116] [INFO] Booting worker with pid: 116
flask_1 | [2019-02-23 09:08:49 +0000] [120] [INFO] Booting worker with pid: 120
flask_1 | [2019-02-23 09:08:50 +0000] [124] [INFO] Booting worker with pid: 124
flask_1 | [2019-02-23 09:08:52 +0000] [128] [INFO] Booting worker with pid: 128
Hier ist docker-compose.yml
:
version: '3'
services:
flask:
build: .
command: gunicorn -b 0.0.0.0:5000 hello:app --reload
environment:
- FLASK_APP=hello.py
- FLASK_DEBUG=1
- PYTHONUNBUFFERED=True
ports:
- "5000:5000"
volumes:
- ./:/root
Welches Docker-Image verwendet es?
@benoitc
[ec2-user@ip-172-31-85-181 web-services-course]$ docker --version
Docker version 18.06.1-ce, build e68fc7a215d7133c34aa18e3b72b4a21fd0c6136
[ec2-user@ip-172-31-85-181 web-services-course]$ docker-compose --version
docker-compose version 1.23.2, build 1110ad01
Hier die Links fĂŒr:
herausgefunden, dass es durch Speichermangel verursacht werden könnte. Die App benötigt mehr Speicher als verfĂŒgbar ist.
aber das ist nur eine vermutung
Nur zur Information: Ich hatte genau dieses Verhalten beobachtet, wenn ich eine gunicorn conf an 3 Worker habe, aber ich habe den Code in einer virtuellen Maschine mit einer Single-Core-CPU bereitgestellt. Dann Àndere ich die Umgebung, um 2 Kerne zu verwenden, und das Problem ist offensichtlich verschwunden
Warum wird "Worker Exit" nur auf der Ebene INFO angezeigt - warum sollte ein Worker nur aufgrund eines Fehlers verlassen werden? Es hat lange gedauert, bis ich herausgefunden habe, dass meine Worker-Threads vom OOM-Killer des Systems getötet wurden, und in den Protokollen gab es nichts auĂer, wie von einigen anderen oben berichtet, von Zeit zu Zeit 'Booting worker with pid'.
@HughWarrington, weil das Beenden eines Workers nicht unbedingt ein Fehler ist. Arbeiter können durch Signale oder Optionen wie --max-requests
.
@HughWarrington wir könnten wahrscheinlich die Anmeldung beim Arbiter hinzufĂŒgen, wenn ein Arbeiter mit einem anormalen Exit-Code beendet wird.
Sie können dafĂŒr ein Ticket eröffnen oder eine PR beisteuern, die diesen Code zur Methode reap_workers
hinzufĂŒgt.
Ich hatte das gleiche Problem und die Lösung bestand darin, die SpeichergröĂe des Pods zu erhöhen.
Hatte das gleiche Problem beim AusfĂŒhren von Gunicorn auf Docker mit einem groĂen spaCy-Modell, es startete die Worker immer wieder ohne Fehlermeldungen neu. Die Lösung besteht darin, den Speicher fĂŒr den Docker-Container zu erhöhen.
Dieses Problem ist heute beim neuesten (19.9.0) gunicorn mit gevent (1.4.0)-Workern aufgetreten, die auf Kubernetes ausgefĂŒhrt werden. Die App ist eine Falcon- App und das Docker-Image ist das offizielle Python-Image mit dem Tag 3.7.3
.
[2019-07-05 00:07:42 +0000] [8] [INFO] Starting gunicorn 19.9.0
[2019-07-05 00:07:42 +0000] [8] [INFO] Listening at: http://0.0.0.0:5000 (8)
[2019-07-05 00:07:42 +0000] [8] [INFO] Using worker: gevent
[2019-07-05 00:07:43 +0000] [35] [INFO] Booting worker with pid: 35
[2019-07-05 00:07:43 +0000] [36] [INFO] Booting worker with pid: 36
[2019-07-05 00:07:43 +0000] [37] [INFO] Booting worker with pid: 37
[2019-07-05 00:07:43 +0000] [38] [INFO] Booting worker with pid: 38
[2019-07-05 00:07:43 +0000] [41] [INFO] Booting worker with pid: 41
[2019-07-05 00:07:43 +0000] [43] [INFO] Booting worker with pid: 43
[2019-07-05 00:07:43 +0000] [45] [INFO] Booting worker with pid: 45
[2019-07-05 00:07:43 +0000] [49] [INFO] Booting worker with pid: 49
[2019-07-05 00:07:43 +0000] [47] [INFO] Booting worker with pid: 47
[2019-07-05 00:07:49 +0000] [53] [INFO] Booting worker with pid: 53
[2019-07-05 00:07:50 +0000] [54] [INFO] Booting worker with pid: 54
[2019-07-05 00:07:53 +0000] [57] [INFO] Booting worker with pid: 57
[...]
Der Pod hatte die folgenden Ressourceneinstellungen:
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
Alles zu verdoppeln hat das Problem behoben.
Eine interessante Sache, die uns aufgefallen ist, war, dass wir beim Betrachten von dmesg
auf dem Host-Rechner sehen können, dass es segfault
-ing bei libcrypto
wenn wir mit SSL auf den Server zugreifen
Speicher scheint fĂŒr mich kein Problem zu sein, da ich kein groĂes Modell in den Speicher lade. Die Mitarbeiter stĂŒrzen immer wieder ab und ich kann keine Fehlermeldungen sehen. Gibt es dafĂŒr eine Lösung?
gleiches Problem bei mir, eine Idee zur Lösung? Python 3.6.3 mit Gunicorn 19.9.0
@MrKiven was macht deine App? Benutzt du Sachen wie Request?
kann jemand eine Möglichkeit bieten, das Problem zu reproduzieren?
Es ist ein Manager mehrerer Komponenten, die in einer Pipeline ausgefĂŒhrt werden. Einige von ihnen starten möglicherweise HTTP-Anforderungen an andere Komponenten auf demselben Computer oder auf Remote-Computern. Einige der Module der Pipeline können parallel ausgefĂŒhrt werden, werden jedoch mit einem ThreadPoolExecutor ausgefĂŒhrt. Sie verwenden keine Shared Objects, sondern generieren nur Datenstrukturen, die spĂ€ter zu einem einzigen Ergebnis zusammengefasst werden.
Leider bin ich mir nicht sicher, ob ich ein Minimalbeispiel zusammenstellen kann, ohne das System, das wir haben, offenzulegen.
request macht viele unsichere Dinge mit Threads, die manchmal einen neuen Prozess abzweigen. Ich wĂŒrde empfehlen, einen anderen Client zu verwenden. Können Sie zumindest die Zeilen einfĂŒgen, die Sie fĂŒr eine Anfrage verwenden? Verwenden Sie die Timeout-Funktion?
Einer davon könnte sein:
try:
resp = requests.post(self._endpoint, json=request_data)
if resp.status_code != 200:
logger.critical("[Error]: status code is {}".format(resp.status_code))
return None
response = resp.json()
return {"intent": response["intent"], "intent_ranking": response["intent_ranking"]}
except ConnectionError as exc:
logger.critical("[Exception] {}".format(str(exc)))
return None
Vielen Dank. Ich werde versuchen, daraus eine einfache zu erstellen.
Es wÀre sowieso cool, wenn uns jemand eine PR schicken könnte, die das Verhalten entweder als Beispiel oder als Komponententest reproduziert, damit wir sicherstellen können, dass wir tatsÀchlich das Richtige reparieren.
Ich bin mir nicht sicher, ob es jemandem helfen kann, aber ich hatte das gleiche Problem beim AusfĂŒhren einer dockerisierten Kolben-Webapp und habe es gelöst, indem ich das Basisbild meiner Dockerdatei auf python:3.6.9-alpine
aktualisiert habe
Dmesg auf dem Host zeigte einen Segfault auf lilibpython3.6m.so.1.0:
[626278.653010] gunicorn[19965]: segfault at 70 ip 00007f6423e7faee sp 00007ffc4e9a2a38 error 4 in libpython3.6m.so.1.0[7f6423d8a000+194000]
Mein Docker-Image basierte auf python:3.6-alpine
und machte ein apk update
das Python auf 3.6.8 aktualisierte.
Wie gesagt, das Ăndern des Basisbilds in python:3.6.9-alpine
es fĂŒr mich gelöst
Ich stand vor der gleichen Herausforderung, einen Flask + Docker + Kubernetes zu betreiben. Das Erhöhen der CPU- und Speichergrenzen hat es fĂŒr mich gelöst.
Uns ist das gleiche passiert. Das Erhöhen der Ressourcenlimits hat das Problem behoben.
Dies passierte mir plötzlich auf macOS Catalina (nicht containerisiert).
Was mir geholfen hat ist:
brew install openssl
~/.zshrc
:export DYLD_LIBRARY_PATH=/usr/local/opt/openssl/lib:$DYLD_LIBRARY_PATH
Habe eine Àhnliche Herausforderung und wÀre dankbar, wenn mir jemand helfen kann.
Das hatte ich;
" root@ubuntu-s-1vcpu-1gb-nyc1-01 :~# sudo systemctl status gunicorn.service â gunicorn.service - gunicorn-Daemon Geladen: geladen (/etc/systemd/system/gunicorn.service; deaktiviert; Herstellervoreinstellung: aktiviert) Aktiv: aktiv (lĂ€uft) seit Mo. 2020-02-24 07:48:04 UTC; vor 44min Main PID: 4846 (gunicorn) Tasks: 4 (Limit: 1151) CGroup: /system.slice/gunicorn.service 4846 /home/bright/djangoprojectdir/djangoprojectenv/bin/python /home/bright/djangoprojectdir/djangoprojectenv/bin/gunicorn - ââ4866 /home/bright/djangoprojectdir/djangoprojectenv/bin/python /home/bright/djangoprojectenv .django /bin/gunicorn - 4868 /home/bright/djangoprojectdir/djangoprojectenv/bin/python /home/bright/djangoprojectdir/djangoprojectenv/bin/gunicorn - ââ4869 /home/bright/djangoprojectdir/djangoprojectenv/bin/python /home /bright/djangoprojectdir/djangoprojectenv/bin/gunicorn - 24. Feb. 07:48:04 ubuntu-s-1vcpu-1gb-nyc1-01 systemd[1]: Gunicorn-Daemon gestoppt 24. Feb. 07:48:04 ubuntu-s-1vcpu -1gb-nyc1-01 systemd[1 ]: Gunicorn-Daemon gestartet. 24. Feb. 07:48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn[4846]: [2020-02-24 07:48:05 +0000] [4846] [INFO] Start gunicorn 20.0.4 24. Feb 07:48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn[4846]: [2020-02-24 07:48:05 +0000] [4846] [INFO] Anhören unter: unix:/run/gunicorn .soc 24. Feb. 07:48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn[4846]: [2020-02-24 07:48:05 +0000] [4846] [INFO] Worker verwenden: sync Feb 24 07:48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn[4846]: [2020-02-24 07:48:05 +0000] [4866] [INFO] Booten des Workers mit pid: 4866 Feb 24 07:48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn[4846]: [2020-02-24 07:48:05 +0000] [4868] [INFO] Booten des Workers mit pid: 4868 Feb 24 07 :48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn[4846]: [2020-02-24 07:48:05 +0000] [4869] [INFO] Booten des Workers mit pid: 4869 Feb 24 08: 03:41 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn[4846]: - - [24/Feb/2020:08:03:41 +0000] "GET / HTTP/1.0" 400 26 "-" "Mozilla /5.0 (Wi-Linien 1-20/20 (ENDE)" Kann mir bitte jemand helfen, das zu beheben?
@BrightNana kannst du versuchen, dmesg
und zu sehen, ob du irgendwelche Gunicorn-Fehler hast?
dmesg | grep gunicorn
könnte helfen, die anderen Fehler herauszufiltern
Hallo,
ich habe den gleichen fehler in debian 9, wenn ich gunicorn als systemd-dienst bereitstellen möchte. Wenn ich es ĂŒber die CLI starte, lĂ€uft gunicorn ohne Fehler.
Auszug aus dmesg | grep gunicorn
:
Auszug aus journalctl
:
MĂ€r 12 07:01:06 build-server gunicorn[828]: [2020-03-12 07:01:06 +0100] [1054] [INFO] Booting worker with pid: 1054 MĂ€r 12 07:01:06 build-server gunicorn[828]: [2020-03-12 07:01:06 +0100] [1057] [INFO] Booting worker with pid: 1057 MĂ€r 12 07:01:06 build-server gunicorn[828]: [2020-03-12 07:01:06 +0100] [1060] [INFO] Booting worker with pid: 1060 MĂ€r 12 07:01:07 build-server gunicorn[828]: [2020-03-12 07:01:07 +0100] [1064] [INFO] Booting worker with pid: 1064 MĂ€r 12 07:01:07 build-server gunicorn[828]: [2020-03-12 07:01:07 +0100] [1067] [INFO] Booting worker with pid: 1067 MĂ€r 12 07:01:07 build-server gunicorn[828]: [2020-03-12 07:01:07 +0100] [1070] [INFO] Booting worker with pid: 1070 MĂ€r 12 07:01:07 build-server gunicorn[828]: [2020-03-12 07:01:07 +0100] [1073] [INFO] Booting worker with pid: 1073 MĂ€r 12 07:01:07 build-server gunicorn[828]: [2020-03-12 07:01:07 +0100] [1076] [INFO] Booting worker with pid: 1076 MĂ€r 12 07:01:08 build-server gunicorn[828]: [2020-03-12 07:01:08 +0100] [1079] [INFO] Booting worker with pid: 1079 MĂ€r 12 07:01:08 build-server gunicorn[828]: [2020-03-12 07:01:08 +0100] [1082] [INFO] Booting worker with pid: 1082 MĂ€r 12 07:01:08 build-server gunicorn[828]: [2020-03-12 07:01:08 +0100] [1085] [INFO] Booting worker with pid: 1085 MĂ€r 12 07:01:08 build-server gunicorn[828]: [2020-03-12 07:01:08 +0100] [1088] [INFO] Booting worker with pid: 1088 MĂ€r 12 07:01:08 build-server gunicorn[828]: [2020-03-12 07:01:08 +0100] [1091] [INFO] Booting worker with pid: 1091 MĂ€r 12 07:01:09 build-server gunicorn[828]: [2020-03-12 07:01:09 +0100] [1094] [INFO] Booting worker with pid: 1094
Auszug aus systemctl status
:
â api.service - API Server for BuildingChallenge served with Gunicorn Loaded: loaded (/etc/systemd/system/api.service; disabled; vendor preset: enabled) Active: active (running) since Thu 2020-03-12 08:26:01 CET; 22min ago Main PID: 8150 (gunicorn) Tasks: 3 (limit: 4915) Memory: 37.7M (high: 100.0M max: 500.0M) CGroup: /system.slice/api.service ââ 8150 /opt/api/venv/bin/python /opt/api/venv/bin/gunicorn --bind unix:api.sock wsgi:app ââ28936 /opt/api/venv/bin/python /opt/api/venv/bin/gunicorn --bind unix:api.sock wsgi:app ââ28938 /usr/bin/python3 -Es /usr/bin/lsb_release -a MĂ€r 12 08:48:01 build-server gunicorn[8150]: [2020-03-12 08:48:01 +0100] [28909] [INFO] Booting worker with pid: 28909 MĂ€r 12 08:48:01 build-server gunicorn[8150]: [2020-03-12 08:48:01 +0100] [28912] [INFO] Booting worker with pid: 28912 MĂ€r 12 08:48:01 build-server gunicorn[8150]: [2020-03-12 08:48:01 +0100] [28915] [INFO] Booting worker with pid: 28915 MĂ€r 12 08:48:01 build-server gunicorn[8150]: [2020-03-12 08:48:01 +0100] [28918] [INFO] Booting worker with pid: 28918 MĂ€r 12 08:48:01 build-server gunicorn[8150]: [2020-03-12 08:48:01 +0100] [28921] [INFO] Booting worker with pid: 28921 MĂ€r 12 08:48:01 build-server gunicorn[8150]: [2020-03-12 08:48:01 +0100] [28924] [INFO] Booting worker with pid: 28924 MĂ€r 12 08:48:02 build-server gunicorn[8150]: [2020-03-12 08:48:02 +0100] [28927] [INFO] Booting worker with pid: 28927 MĂ€r 12 08:48:02 build-server gunicorn[8150]: [2020-03-12 08:48:02 +0100] [28930] [INFO] Booting worker with pid: 28930 MĂ€r 12 08:48:02 build-server gunicorn[8150]: [2020-03-12 08:48:02 +0100] [28933] [INFO] Booting worker with pid: 28933 MĂ€r 12 08:48:02 build-server gunicorn[8150]: [2020-03-12 08:48:02 +0100] [28936] [INFO] Booting worker with pid: 28936
Danke fĂŒr Ihre Hilfe.
Ich habe eine PR erstellt, die helfen könnte, solche Situationen zu beheben. Kann jemand nachschauen?
https://github.com/benoitc/gunicorn/pull/2315
Ich hatte das gleiche Problem mit einer Flask-Anwendung, die in Docker ausgefĂŒhrt wurde. Die Arbeiter starteten endlos mit steigender Prozess-ID neu.
Das Problem war fĂŒr mich mit dem Speicher verbunden, als ich den fĂŒr Docker zugelassenen Speicher erhöhte, spawnten die Arbeiter effektiv.
@tilgovi , es macht mir nichts aus, wenn Sie meine Ănderungen in Ihre PR
@mildebrandt ich schau mal, danke!
Ich sehe dieses Verhalten auch plötzlich, wenn ich Gunicorn (20.0.4) + Gevent (1.5.0) + Flask in einem Docker-Container verwende.
[ 328.699160] gunicorn[5151]: segfault at 78 ip 00007fc1113c16be sp 00007ffce50452a0 error 4 in _greenlet.cpython-37m-x86_64-linux-gnu.so[7fc11138d000+3e000]
In meinem Fall wird der Segfault, wie Sie sehen können, durch gevent verursacht. Seltsam ist, dass dieser Container vor 5 Tagen gut funktioniert hat und keine der CodeÀnderungen seitdem irgendeine Version einer der Bibliotheken geÀndert hat und alle auf bestimmte Releases eingestellt sind. Ich habe Flask-Mail als AbhÀngigkeit entfernt, was die Versionen anderer AbhÀngigkeiten möglicherweise leicht verÀndert hat.
Das Aktualisieren von gevent==1.5.0 auf gevent==20.9.0 hat das Problem fĂŒr mich behoben.
@ifiddes Ihr Problem hat wahrscheinlich https://github.com/python-greenlet/greenlet/issues/178
Ah, danke @jamadden. Dieser Beitrag war alles, was ich finden konnte, als ich nach unendlich vielen Booten von Arbeitern suchte, aber dieses Problem und der Zeitpunkt dieses Problems passten zu meinem Problem.
Ich hatte einen Àhnlichen Fehler mit einem neuen AWS- Computer mit Ubuntu 20.04 Server und mit demselben Code, der in der Produktion funktioniert.
Die Maschine wurde wie die anderen Produktionsmaschinen mit Ansible konfiguriert.
[2020-10-15 15:11:49 +0000] [18068] [DEBUG] Current configuration:
config: None
bind: ['127.0.0.1:8000']
backlog: 2048
workers: 1
worker_class: uvicorn.workers.UvicornWorker
threads: 1
worker_connections: 1000
max_requests: 0
max_requests_jitter: 0
timeout: 30
graceful_timeout: 30
keepalive: 2
limit_request_line: 4094
limit_request_fields: 100
limit_request_field_size: 8190
reload: False
reload_engine: auto
reload_extra_files: []
spew: False
check_config: False
preload_app: False
sendfile: None
reuse_port: False
chdir: /var/www/realistico/app
daemon: False
raw_env: []
pidfile: None
worker_tmp_dir: None
user: 1001
group: 1001
umask: 0
initgroups: False
tmp_upload_dir: None
secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}
forwarded_allow_ips: ['127.0.0.1']
accesslog: /var/www/realistico/logs/gunicorn/access.log
disable_redirect_access_to_syslog: False
access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
errorlog: /var/www/realistico/logs/gunicorn/error.log
loglevel: debug
capture_output: False
logger_class: gunicorn.glogging.Logger
logconfig: None
logconfig_dict: {}
syslog_addr: udp://localhost:514
syslog: False
syslog_prefix: None
syslog_facility: user
enable_stdio_inheritance: False
statsd_host: None
dogstatsd_tags:
statsd_prefix:
proc_name: None
default_proc_name: realistico.asgi:application
pythonpath: None
paste: None
on_starting: <function OnStarting.on_starting at 0x7f7ba5fdd550>
on_reload: <function OnReload.on_reload at 0x7f7ba5fdd670>
when_ready: <function WhenReady.when_ready at 0x7f7ba5fdd790>
pre_fork: <function Prefork.pre_fork at 0x7f7ba5fdd8b0>
post_fork: <function Postfork.post_fork at 0x7f7ba5fdd9d0>
post_worker_init: <function PostWorkerInit.post_worker_init at 0x7f7ba5fddaf0>
worker_int: <function WorkerInt.worker_int at 0x7f7ba5fddc10>
worker_abort: <function WorkerAbort.worker_abort at 0x7f7ba5fddd30>
pre_exec: <function PreExec.pre_exec at 0x7f7ba5fdde50>
pre_request: <function PreRequest.pre_request at 0x7f7ba5fddf70>
post_request: <function PostRequest.post_request at 0x7f7ba5f6e040>
child_exit: <function ChildExit.child_exit at 0x7f7ba5f6e160>
worker_exit: <function WorkerExit.worker_exit at 0x7f7ba5f6e280>
nworkers_changed: <function NumWorkersChanged.nworkers_changed at 0x7f7ba5f6e3a0>
on_exit: <function OnExit.on_exit at 0x7f7ba5f6e4c0>
proxy_protocol: False
proxy_allow_ips: ['127.0.0.1']
keyfile: None
certfile: None
ssl_version: 2
cert_reqs: 0
ca_certs: None
suppress_ragged_eofs: True
do_handshake_on_connect: False
ciphers: None
raw_paste_global_conf: []
strip_header_spaces: False
[2020-10-15 15:11:49 +0000] [18068] [INFO] Starting gunicorn 20.0.4
[2020-10-15 15:11:49 +0000] [18068] [DEBUG] Arbiter booted
[2020-10-15 15:11:49 +0000] [18068] [INFO] Listening at: unix:/run/gunicorn.sock (18068)
[2020-10-15 15:11:49 +0000] [18068] [INFO] Using worker: uvicorn.workers.UvicornWorker
[2020-10-15 15:11:49 +0000] [18080] [INFO] Booting worker with pid: 18080
[2020-10-15 15:11:49 +0000] [18068] [DEBUG] 1 workers
[2020-10-15 15:11:51 +0000] [18083] [INFO] Booting worker with pid: 18083
[2020-10-15 15:11:53 +0000] [18086] [INFO] Booting worker with pid: 18086
...
[2020-10-15 15:12:09 +0000] [18120] [INFO] Booting worker with pid: 18120
[2020-10-15 15:12:11 +0000] [18123] [INFO] Booting worker with pid: 18123
Nachdem ich viele Zeit verloren hatte, um dieses Problem ohne Erfolg zu lösen (und ohne Fehler in den Protokollen), habe ich es mit dieser Hallo Welt versucht und diesen Fehler gefunden:
ModuleNotFoundError: No module named 'httptools'
Nach der Installation von httptools
funktioniert die Hello World- Anwendung einwandfrei und unerwarteterweise funktioniert auch meine Anwendung.
Ich habe keine Ahnung, warum der Fehler nicht protokolliert wurde oder warum diese Bibliothek auf den anderen Computern installiert wurde, aber nicht auf dem neuen, aber dies behebt das Problem fĂŒr mich.
WĂ€re dies kĂŒrzlich passiert und hĂ€tte den Kubernetes-Knoten, auf dem er sich befand, heruntergefahren, indem die gesamte CPU verbraucht wurde. Dank des Hinweises zu dmesg
ich schlieĂlich einen Fehler gefunden:
[225027.348869] traps: python[44796] general protection ip:7f8bd8f8f8b0 sp:7ffc21a0b370 error:0 in libpython3.7m.so.1.0[7f8bd8dca000+2d9000]
Am Ende war mein Problem eine weitere Instanz von https://github.com/python-greenlet/greenlet/issues/178 und wurde durch die Aktualisierung von gunicorn, gevent und greenlet auf die neueste Version behoben.
Da diese Arten von Ausnahmen keine Python-Protokolle erstellen, nicht abgefangen werden können, den Exit-Code 0 zurĂŒckgeben und die Maschine hĂ€ngen können, wenn sie auftreten, sind sie ziemlich schwierig zu verwalten.
Ich schlage vor, dass Gunicorn schnelle Crash-Loops dieser Art erkennt und
vielleicht max_consecutive_startup_crashes
mit dem Standardwert num_workers * 10 ?
Lassen Sie uns die Anforderung der Crash-Loop-Funktion in #2504 verfolgen. Wir haben auch die PR fĂŒr zusĂ€tzliches Einloggen in #2315. Ich werde dieses Thema schlieĂen, da es so aussieht, als ob jeder seine Probleme behoben hat und wir jetzt einige Funktionsanfragen und Verbesserungen haben, um anderen in Zukunft zu helfen. Danke, alle!
Hilfreichster Kommentar
Nur ein Update, das Problem war fĂŒr mich eigentlich ein Speicherfehler und wurde behoben, als das Speicherproblem behoben wurde.