Я пытаюсь настроить Gunicorn на Docker. Он хорошо работает локально, и производственный образ точно такой же, как и локальный образ, но я получаю такое странное поведение в производственном движке Docker:
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.
Похоже, Gunicorn загружает рабочих каждые 4-5 секунд, несмотря на отсутствие явных сообщений об ошибках или сигналов выхода. Такое поведение продолжается бесконечно, пока не будет прекращено.
Возможно ли, что воркер может выйти, ничего не записывая в stderr / stdout, или чтобы арбитр мог бесконечно порождать воркеров?
Поскольку это один и тот же образ докера, они запускают один и тот же код на одной и той же архитектуре, поэтому я действительно не понимаю, что это может быть (ошибка?). Любая помощь очень ценится!
ssh
-ing в контейнер Docker заставил меня найти эту ошибку:
Illegal instruction (core dumped)
Может быть, Gunicorn следует выявлять подобные ошибки, а не глотать их, или обращаться с ними по-другому? Не уверен, просто подумал, что подниму это, потому что это может помочь кому-то другому!
Благодарим за сообщение о проблеме!
Если вы сможете выяснить, где это происходит, это будет очень полезно.
Возможно, мы сможем добавить логирование при выходе рабочих. Обычно сам воркер записывает в журнал, но если его очень резко убить, этого не произойдет.
Не стоит беспокоиться!
Кажется, проблема с Spacy, которую я только что добавил в эту ветку: https://github.com/explosion/spaCy/issues/1589
В любом случае, это вызывает SIGILL
поскольку strace
подтверждает:
--- SIGILL {si_signo=SIGILL, si_code=ILL_ILLOPN, si_addr=0x7ff48bbe6cea} ---
+++ killed by SIGILL (core dumped) +++
Illegal instruction (core dumped)
Я полагаю, было бы неплохо, если бы Gunicorn мог идентифицировать это и регистрировать ошибку, а не фантомно перезапускать воркера, но, черт возьми, я очень мало знаю о том, как работают коды выхода!
Некоторые коды выхода определенно имеют особое значение, и мы, вероятно, могли бы их зарегистрировать.
http://tldp.org/LDP/abs/html/exitcodes.html
Звучит отлично! Кроме того, если код выхода не является зарезервированным кодом выхода (как в этом случае), было бы здорово, если бы это можно было зарегистрировать (без объяснения причин), чтобы было очевидно, что рабочий процесс действительно завершает работу 🙂
У меня похожая проблема, Gunicorn всегда загружает нового рабочего, когда я делаю HTTP-запрос. Я не получаю никакого ответа, он просто всегда перезагружает нового рабочего. Журнал Strace из двух HTTP-запросов:
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
Я столкнулся с той же проблемой: gunicorn
загружается повторно в течение нескольких секунд для рабочего типа sync
. Установка тайм-аута рабочего на 900
не помогает.
В моей загрузке перед действием я загружаю данные из AWS S3. Загрузка различных файлов занимает около 1 минуты 10 секунд.
@ sara-02 какая у вас командная строка для запуска пулеметчика?
@benoitc gunicorn --pythonpath /src -b 0.0.0.0:$SERVICE_PORT --workers=1 -k sync -t $SERVICE_TIMEOUT flask_endpoint:app
Присутствовать здесь
@ sara-02 Спасибо.
Действительно ли старые рабочие уходят или они остаются в сети и появляются новые рабочие? Что также показывает журнал отладки?
Журналы смешаны с журналами ботокора, но это примерно так
[INFO] Booting worker with pid: a
[INFO] Booting worker with pid: b
[INFO] Booting worker with pid: c
а рабочий убит? что вернуть команду ps ax|grep gunicorn
?
@benoitc
Однако возникает вопрос: почему мы видим 2 процесса gunicorn
, когда ограничение числа рабочих установлено равным 1? Один хозяин и один рабочий?
Есть 1 процесс-арбитр (мастер) и N рабочих процессов ye :)
Значит, вы запускаете команду каждый раз, когда рабочий загружается, верно? Если это так, кажется, что старый рабочий убит, создается новый. Я займусь расследованием.
@ sara-02 и последнее, это тоже происходит в докере?
@benoitc на docker-compose
работает, как ожидалось, но когда я помещаю тот же код на Openshift
, я вижу эту ошибку. Увеличение требований к памяти исправлено, но когда я запускаю приложение через docker-compose
оно использует меньше limited
памяти.
Просто обновление, проблема для меня на самом деле была ошибкой памяти и была исправлена, когда проблема с памятью была исправлена.
@benoitc
Я столкнулся с той же проблемой при попытке создать 5 рабочих-пулеметчиков в докере.
@ sara-02
Как вы определили причину ошибки памяти?
@ gulshan-gaurav мне помогли 2 вещи:
Я увеличил память, выделенную для моего пода, и перестал давать сбой. Во-вторых, мы проверили наши журналы Openshift Zabbix.
@ sara-02
Даже в моем промежуточном модуле файлы + модели, которые я загружаю в память, составляют 50 МБ, поэтому 2 ГБ памяти должно быть достаточно для 5 рабочих.
@ gulshan-gaurav, с какой проблемой вы столкнулись? Имея там 5 процессов выглядит хорошо ....
Я была такая же проблема. Я не обнаружил точной проблемы, но она была решена после того, как я обновил python 3.5 до 3.6.
Я столкнулся с той же проблемой в контейнере Docker. Gunicorn продолжает загружать нового воркера каждый раз, когда я вызываю конечную точку, которая вызывает сбой, но в файлы журнала Gunicorn не выводится исключение или ошибка. То, что я выбираю для печати, записывается в журнал, а затем внезапно в файле журнала просто говорится: «Загрузка рабочего с pid ...»
Один из шагов, который помог, заключался в добавлении переменной env PYTHONUNBUFFERED. До этого исчезли даже операторы печати, которые не сохранялись в журналах Gunicorn.
2 другие конечные точки приложения работают правильно.
Я запускаю Gunicorn с помощью: 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 отладка
Уже запущен Python 3.6 и проверил с помощью top, что память, похоже, не является проблемой.
РЕДАКТИРОВАТЬ: Похоже, это проблема Python, а не ошибка Gunicorn. Некоторые несоответствия версий приводили к тому, что Python просто бесследно умирал при выполнении определенной операции.
Я столкнулся с аналогичной проблемой, когда рабочий узел продолжает придумывать
Booting worker with pid: 17636
. Я не знаю, убивает ли он предыдущий рабочий узел или предыдущий рабочий узел все еще существует. Но количество рабочих, упомянутых в аргументах командной строки gunicorn, составляет всего 3 - -workers=3
. Также я использую Python версии 3.7.
У меня было несоответствие зависимости scikit-learn, но даже после его решения я получаю все те же бесконечные рабочие. какие расхождения в версиях Python мне следует искать и как их идентифицировать?
У меня такая же проблема внутри OpenShift.
Как вы можете видеть на изображении, я использую 6 воркеров (я пробовал с 3).
Я увеличил память пода, и он не работает.
BuildConfig:
Любая идея?
Спасибо
вы запускаете это в aws за elb? Я решил эту проблему, поместив nginx ingress между elb и gunicorn
Есть такая же проблема.
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
Вот 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
какой образ докера он использует?
@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
Вот ссылки на:
понял, что это может быть вызвано нехваткой памяти. приложению требуется больше памяти, чем доступно.
но это просто предположение
Так же как информация: я наблюдал именно такое поведение, когда у меня был конфигурирован пулемет для 3 рабочих, но я развернул код на виртуальной машине с одноядерным процессором. Затем я меняю среду, чтобы использовать 2 ядра, и, очевидно, проблема исчезла.
Почему «Рабочий выходит» только на уровне ИНФОРМАЦИЯ - почему рабочий должен завершать работу, кроме как в результате ошибки? Мне потребовалось много времени, чтобы понять, что мои рабочие потоки были убиты системным убийцей OOM, и в журналах ничего не было, кроме, как сообщали некоторые другие выше, «Загрузка рабочего с pid» время от времени.
@HughWarrington, потому что выход рабочего не обязательно является ошибкой. Рабочие могут быть завершены сигналами или такими опциями, как --max-requests
.
@HughWarrington, возможно, мы могли бы добавить логирование в арбитр, когда рабочий выходит с аномальным кодом выхода.
Вы можете открыть билет для этого или внести PR, который добавит этот код к методу reap_workers
.
У меня была такая же проблема, и я решил увеличить объем памяти модуля.
Была такая же проблема с запуском Gunicorn на Docker с большой моделью spaCy, он продолжал перезапускать воркеры без каких-либо сообщений об ошибках. Решение - увеличить память для контейнера Docker.
Только что столкнулся с этой проблемой сегодня на последней версии (19.9.0) gunicorn с рабочими процессами gevent (1.4.0), работающими на Kubernetes. Это приложение Falcon , а образ Docker - это официальный образ Python с тегом 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
[...]
У модуля были следующие настройки ресурсов:
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
Удвоение всего устранило проблему.
Мы заметили одну интересную вещь: глядя на dmesg
на хост-машине, мы можем видеть, что это segfault
-ing в libcrypto
при доступе к серверу с использованием SSL.
Память для меня не проблема, потому что я не загружаю в память какую-либо большую модель. Рабочие просто продолжают давать сбой, и я не вижу сообщений об ошибках. Это можно как-то исправить?
такая же проблема для меня, есть идеи исправить? Python 3.6.3 с Gunicorn 19.9.0
@MrKiven, что делает ваше приложение? вы используете такие вещи, как запрос?
может кто-нибудь предоставляет способ воспроизвести проблему?
Это менеджер нескольких компонентов, которые выполняются в конвейере. Некоторые из них могут запускать HTTP-запросы к другим компонентам на той же машине или на удаленных машинах. Некоторые модули конвейера могут выполняться параллельно, но они выполняются с помощью ThreadPoolExecutor. Они не используют никаких общих объектов, а только генерируют структуры данных, которые позже объединяются в единую результирующую.
К сожалению, я не уверен, что смогу собрать минимальный пример, не раскрывая нашу систему.
request делает много небезопасных вещей с потоками, которые иногда разветвляют новый процесс. Я бы посоветовал использовать другого клиента. вы можете вставить хотя бы те строки, которые вы используете для выполнения запроса? Вы используете его функцию тайм-аута?
Одним из них может быть:
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
Спасибо. Я постараюсь создать из него простой.
В любом случае было бы здорово, если бы кто-то мог прислать нам PR, который воспроизводит поведение либо в качестве примера, либо в качестве модульного теста, чтобы мы убедились, что действительно исправляем правильную вещь.
Не уверен, что это может помочь кому-то, но у меня была такая же проблема при запуске докеризованного веб-приложения фляги, и я решил ее, обновив базовый образ моего файла докеров до python:3.6.9-alpine
Dmesg на хосте обнаружил ошибку сегментации 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]
Мой образ докера был основан на python:3.6-alpine
и выполнял apk update
который обновлял python до 3.6.8.
Как сказано, изменение базового изображения на python:3.6.9-alpine
решило это для меня.
Я столкнулся с той же проблемой, запустив Flask + Docker + Kubernetes. Увеличение пределов ЦП и памяти решило эту проблему для меня.
То же самое случилось и с нами. Проблема была решена увеличением лимитов ресурсов.
Это внезапно случилось со мной на macOS Catalina (не в контейнерах).
Мне помогли:
brew install openssl
~/.zshrc
:export DYLD_LIBRARY_PATH=/usr/local/opt/openssl/lib:$DYLD_LIBRARY_PATH
У меня аналогичная проблема, и буду благодарен, если кто-нибудь сможет мне помочь.
Вот что у меня было;
" root @ ubuntu-s-1vcpu-1gb-nyc1-01 : ~ # sudo systemctl status gunicorn.service ● gunicorn.service - демон gunicorn Загружен: загружен (/etc/systemd/system/gunicorn.service; отключен; предустановка поставщика: enabled) Активен: активен (работает) с понедельника 2020-02-24 07:48:04 UTC; 44мин назад Основной PID: 4846 (gunicorn) Задач: 4 (ограничение: 1151) CGroup: /system.slice/gunicorn.service ├ ─4846 / home / bright / djangoprojectdir / djangoprojectenv / bin / python / home / bright / djangoprojectdir / djangoprojectenv / bin / gunicorn - ├─4866 / home / bright / djangoprojectdir / djangoprojectenc / djangoprojectdir / djangoprojectenctenc / djangoprojectdir / djangoprojectenctenc / binv / djangoprojectenc / binv / djangoprojectenc / binv / djangoprojectenc / binv / djangoprojectenc / binv / djangoprojectenc / djangoprojectdir / home / djangoprojectenc / bin / django / / bin / gunicorn - ├─4868 / home / bright / djangoprojectdir / djangoprojectenv / bin / python / home / bright / djangoprojectdir / djangoprojectenv / bin / gunicorn - └─4869 / home / bright / djangoprojectdir / djangoprojecten / home / bin / / bright / djangoprojectdir / djangoprojectenv / bin / gunicorn - 24 февраля 07:48:04 ubuntu-s-1vcpu-1gb-nyc1-01 systemd [1]: остановлен демон-пулемет. 24 февраля 07:48:04 ubuntu-s-1vcpu -1gb-nyc1-01 systemd [1 ]: Запущен демон-пулеметчик. 24 февраля 07:48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn [4846]: [2020-02-24 07:48:05 +0000] [4846] [ИНФОРМАЦИЯ] Запуск Gunicorn 20.0.4 24 февраля 07:48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn [4846]: [2020-02-24 07:48:05 +0000] [4846] [ИНФОРМАЦИЯ] Прослушивание: unix: / run / gunicorn .soc 24 февраля, 07:48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn [4846]: [2020-02-24 07:48:05 +0000] [4846] [ИНФОРМАЦИЯ] Использование worker: sync Feb 24 07:48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn [4846]: [2020-02-24 07:48:05 +0000] [4866] [ИНФОРМАЦИЯ] Загрузка рабочего с pid: 4866 24 февраля 07:48:05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn [4846]: [2020-02-24 07:48:05 +0000] [4868] [ИНФОРМАЦИЯ] Загрузочный рабочий с pid: 4868 24 февраля 2007 г. : 48: 05 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn [4846]: [2020-02-24 07:48:05 +0000] [4869] [ИНФОРМАЦИЯ] Загрузочный рабочий с pid: 4869 24 февраля 08: 03:41 ubuntu-s-1vcpu-1gb-nyc1-01 gunicorn [4846]: - - [24 / фев / 2020: 08: 03: 41 +0000] "GET / HTTP / 1.0" 400 26 "-" "Mozilla /5.0 (Wi-Fi линии 1-20 / 20 (END) «Кто-нибудь, пожалуйста, помогите мне это исправить?
@BrightNana, можете ли вы дать dmesg
и посмотреть, есть ли у вас какие-нибудь ошибки?
dmesg | grep gunicorn
может помочь отфильтровать другие ошибки
Привет,
У меня такая же ошибка в debian 9, когда я хочу предоставить gunicorn в качестве службы systemd. Если я запускаю его из интерфейса командной строки, Gunicorn работает без ошибок.
Извлечение из dmesg | grep gunicorn
:
Отрывок из 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
Извлечение из 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
Спасибо за вашу помощь.
Я выставил PR, который мог бы помочь отладить подобные ситуации. Кто-нибудь может посмотреть?
https://github.com/benoitc/gunicorn/pull/2315
У меня была такая же проблема с приложением Flask, работающим внутри Docker. Рабочие бесконечно перезапускались с увеличивающимся идентификатором процесса.
Для меня проблема была связана с памятью, когда я увеличил объем памяти, разрешенный для Docker, рабочие рождались эффективно.
@tilgovi , я не возражаю, если вы захотите включить мои изменения в свой PR, поскольку вы туда попали первым. Это покроет убитые рабочие с помощью сигналов.
@mildebrandt Я посмотрю, спасибо!
Я также внезапно вижу такое поведение, используя Gunicorn (20.0.4) + Gevent (1.5.0) + Flask внутри контейнера Docker.
[ 328.699160] gunicorn[5151]: segfault at 78 ip 00007fc1113c16be sp 00007ffce50452a0 error 4 in _greenlet.cpython-37m-x86_64-linux-gnu.so[7fc11138d000+3e000]
В моем случае, как вы можете видеть, segfault вызван gevent. Что странно, так это то, что этот контейнер работал нормально 5 дней назад, и с тех пор ни одно из изменений кода не изменило никаких версий какой-либо из библиотек, и все они настроены на определенные выпуски. Я удалил flask-mail как зависимость, которая могла немного изменить версии других зависимостей.
Обновление с gevent == 1.5.0 до gevent == 20.9.0 решило проблему для меня.
@ifiddes, ваша проблема, скорее всего, не связана. Вы видите проблему совместимости ABI между старыми версиями gevent с гринлетом самой последней версии. См. Https://github.com/python-greenlet/greenlet/issues/178
Ах, спасибо @jamadden. Этот пост был всем, что я смог найти при поиске бесконечного порождения загружающихся рабочих, но эта проблема и время ее появления соответствовали моей проблеме.
У меня была аналогичная ошибка с новой машиной AWS с сервером Ubuntu 20.04 и с тем же кодом, который работает в производственной среде.
Машина была настроена с использованием Ansible, как и другие производственные машины.
[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
После многих неудачных попыток решить эту проблему (и без каких-либо ошибок в журналах) я попытался с этим Hello world и обнаружил эту ошибку:
ModuleNotFoundError: No module named 'httptools'
После установки httptools
приложение Hello world работает нормально и, неожиданно, работает и мое приложение.
Я понятия не имею, почему ошибка не была зарегистрирована или почему эта библиотека была установлена на других машинах, но не на новой, но это решило проблему для меня.
Если бы это произошло недавно и отключили узел кубернетов, на котором он был, за счет использования всего ЦП. Благодаря подсказке о dmesg
в конце концов я обнаружил ошибку:
[225027.348869] traps: python[44796] general protection ip:7f8bd8f8f8b0 sp:7ffc21a0b370 error:0 in libpython3.7m.so.1.0[7f8bd8dca000+2d9000]
В конце концов, моя проблема заключалась в другом экземпляре https://github.com/python-greenlet/greenlet/issues/178 и была решена путем обновления gunicorn, gevent и greenlet до последней версии.
Поскольку эти типы исключений не создают журналов Python, не могут быть перехвачены, возвращают код выхода 0 и могут повесить машину, когда они возникают, ими довольно сложно управлять.
Я предлагаю, чтобы пулемет обнаруживал быстрое зацикливание такого рода и
возможно, max_consecutive_startup_crashes
со значением по умолчанию num_workers * 10?
Давайте отследим запрос функции цикла сбоя в # 2504. У нас также есть PR на дополнительный вход в # 2315. Я закрою эту проблему, так как кажется, что все отладили свои проблемы, и теперь у нас есть некоторые запросы функций и улучшения, которые помогут другим в будущем. Спасибо всем!
Самый полезный комментарий
Просто обновление, проблема для меня на самом деле была ошибкой памяти и была исправлена, когда проблема с памятью была исправлена.