Gunicorn: Gunicorn ест больше памяти в django

Созданный на 1 мая 2016  ·  31Комментарии  ·  Источник: benoitc/gunicorn

В проекте django я использую Gunicorn в качестве сервера приложений. В последние несколько дней приложение работает без сбоев в течение нескольких часов после того, как это приложение зависло. Gunicorn использует больше памяти, из-за этого загрузка процессора достигает 95%, и приложение зависает.

Вот моя конфигурация Gunicorn при запуске приложения.
база ганикорн. wsgi:приложение
--bind=0.0.0.0:8000
--pid=журналы/проект/gunicorn.log
--access-logfile=журналы/проект/access.log
--рабочие=7
--worker-класс=gevent
--error-logfile=журналы/проект/error8.log
--время ожидания=4500
--предварительная загрузка

Пожалуйста, помогите мне в этом вопросе.

Feedback Requested

Самый полезный комментарий

просто установите max-requests и очистите рабочий процесс через некоторое время, это должно закрыть любую утечку памяти, которая у вас есть.

Все 31 Комментарий

возможно, вам нужно уменьшить количество рабочих, попробуйте эту формулу 2 * процессоры + 1, ваш сервер может быть с одним процессором, поэтому установите его на 3 безопасно.

любой журнал поделиться? Как воспроизвести? Сам по себе gunicorn не использует много оперативной памяти или процессора. Кроме того, почему вы предварительно загружаете приложение?

@syaiful6 В настоящее время на сервере обрабатываются 4 процессора. по-вашему, я должен установить --workers=4 правильно?

@benoitc В то время, когда 12-15 пользователей входят в систему и выполняют какую-либо деятельность, пушка захватывает больше памяти из-за того, что загрузка ЦП больше, и система зависает.

есть ли способ воспроизвести проблему? Gunicorn сам по себе не использует много процессора, более вероятно, что что-то в вашем приложении вызывает проблему.

удар.

просто установите max-requests и очистите рабочий процесс через некоторое время, это должно закрыть любую утечку памяти, которая у вас есть.

нет ответа, так как эмитент закрыл вопрос тогда.

@hardiksanchawat , вы не должны использовать предварительную загрузку, пока вам действительно не понадобится использовать предварительную загрузку, что может быть одной из причин. Также, как сказал @diwu1989 , вы можете использовать параметр max-requests , чтобы предотвратить утечку памяти.

Мы разместили наше веб-приложение (Angular CLI: 1.7.3, Node: 9.5.0, Django 2.0.3) на бесплатном уровне AWS виртуальной машины Ubuntu (14.04.5 LTS). Мы используем ELB (эластичные балансировщики нагрузки) с Nginx-1.4.6 и gunicorn-19.7.1.

Когда мы пытаемся использовать доступ к нашему приложению из браузера, внезапно использование памяти пушки увеличивается довольно сильно:

Обычный:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
16248 ubuntu 20 0 313,1 м 94,6 м 9,3 м R 15,6 9,5 0:00,71 стрелорог

Во время использования приложения:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
16235 ubuntu 20 0 684,9 м 315,8 м 11,1 м R 61,4 31,8 0:04,51 стрелорог
Ниже приведена конфигурация нашей пушки (/etc/init/gunicorn.conf):

description "Сервер приложений Gunicorn обрабатывает мой проект"

запустить на уровне выполнения [2345]
остановить на уровне запуска [!2345]

респаун
setuid убунту
setgid www-данные
chdir /дом/ubuntu/проект/

exec ./env/bin/gunicorn --max-requests 1 --workers 3 --bind unix:/home/ubuntu/project/django-ng.sock config. wsgi:приложение

Мы уже установили max-requests как 1 и workers как 3. Может ли кто-нибудь сказать, что происходит не так?

@satendrapratap Я не уверен, что что-то не так. Возможно, вам придется профилировать свое приложение, но также возможно, что это процесс Python на машине с 1 ГБ, и у вас есть три рабочих процесса. Это может быть нормально. Сложно сказать.

Ok. Какой профилировщик мы должны использовать для профилирования?

Тот же код хорошо работает с «python3 manage.py runserver», и мы не видим никакого увеличения памяти, используемой в течение определенного периода времени или сразу. Утечек памяти, скорее всего, нет, иначе и в этом случае было бы повышенное потребление памяти.

Как на самом деле может помочь профилирование? Вы хотите сказать, что нам нужно оптимизировать код, чтобы он потреблял меньше памяти?

но также возможно, что это процесс Python на машине с 1 ГБ, и у вас есть три рабочих.

Сколько памяти занимает процесс Python во время выполнения? В нашем случае gunicorn занимает аж 500-600 Мб при всего 1 max-запросе, а если увеличить до 2, то при обращении к приложению иногда выдает ошибку out of memory.

Профилирование @satendrapratap помогло бы, если бы было место, где вы могли бы уменьшить использование памяти вашим собственным приложением.

Также было бы полезно узнать, использует ли Gunicorn больше памяти, чем должен, или есть ли утечка с Gunicorn, которой нет с runserver.

Я только что провел несколько быстрых тестов минимальных приложений, которые, кажется, составляют всего 20-30 МБ для рабочего, но для реального приложения это во многом зависит от приложения и фреймворка.

Меня интересуют любые сравнения между Gunicorn и runserver, которые вы можете предоставить.

В нашем случае gunicorn занимает аж 500-600 Мб при всего 1 max-запросе, а если увеличить до 2, то при обращении к приложению иногда выдает ошибку out of memory.

Обратите внимание, что Python имеет свой собственный распределитель памяти и не возвращает ранее выделенные блоки памяти ОС, поэтому увеличение использования памяти не всегда означает наличие утечки памяти.

Вы видите одинаковое использование памяти для всех URL-адресов или только для определенного URL-адреса (например, /products/all)?

Я бы также предложил развернуть простое приложение Django (та же база данных и конфигурация Gunicorn, только одна модель и пара представлений), чтобы увидеть, является ли Gunicorn причиной высокого использования памяти.

Также было бы полезно узнать, использует ли Gunicorn больше памяти, чем должен, или есть ли утечка с Gunicorn, которой нет с runserver.

Обязательно попробуем профилировать. Не могли бы вы предложить профайлер для использования в таком сценарии?

Я только что сделал несколько быстрых тестов минимальных приложений, которые, кажется, составляют всего 20-30 МБ для рабочего,

У нас есть 3 рабочих, и пока приложение не используется, оно потребляет около 96 МБ:

ubuntu@:~$ sudo python3 ps_mem.py
Private + Shared = ОЗУ используется программой

136,0 КиБ + 9,0 КиБ = 145,0 КиБ acpid
180,0 КиБ + 24,0 КиБ = 204,0 КиБ при загрузке
220,0 КиБ + 38,0 КиБ = 258,0 КиБ upstart-udev-bridge
240,0 КиБ + 34,0 КиБ = 274,0 КиБ cron
236,0 КиБ + 39,0 КиБ = 275,0 КиБ upstart-socket-bridge
288,0 КиБ + 39,5 КиБ = 327,5 КиБ upstart-file-bridge
604,0 КиБ + 50,0 КиБ = 654,0 КиБ
544,0 КиБ + 147,0 КиБ = 691,0 КиБ
684,0 КиБ + 58,0 КиБ = 742,0 КиБ
940,0 КиБ + 56,0 КиБ = 996,0 КиБ rsyslogd
1,0 МБ + 131,5 КиБ = 1,2 МБ getty (7)
896,0 КБ + 400,5 КБ = 1,3 МБ судо
1,4 МБ + 73,0 КиБ = 1,5 МБ инициализации
2,5 МБ + 39,5 КБ = 2,6 МБ dhclient
2,3 МБ + 1,5 МБ = 3,8 МБ nginx (5)
2,5 МБ + 1,8 МБ = 4,3 МБ sshd (3)
6,4 МБ + 176,5 КБ = 6,6 МБ баш
50,1 МБ + 83,0 КБ = 50,2 МБ

87,8 МБ + 7,8 МБ = 95,5 МБ пушкикорн (4)

171,4 МБ

убунту@:~$
ps_mem.py: https://raw.githubusercontent.com/pixelb/ps_mem/master/ps_mem.py

Python имеет собственный распределитель памяти и не возвращает ОС ранее выделенные блоки памяти, поэтому увеличение использования памяти не всегда означает утечку памяти.

Хорошо, но есть ли способ в python, мы можем попросить освободить неиспользуемую память?

Вы видите одинаковое использование памяти для всех URL-адресов или только для определенного URL-адреса (например, /products/all)?

Похоже, что его аналогичное (не большая разница) использование памяти для разных URL-адресов:
URL для получения небольших данных:
19181 ubuntu 20 0 553,8 м 281,4 м 10,0 м R 32,6 28,4 0:01,21 стрелорог
19191 Ubuntu 20 0 97,8 м 34,1 м 2,9 м S 7,7 3,4 0:00,23 стрелорог

URL, чтобы получить немного больше данных:
19196 ubuntu 20 0 97,8 м 34,1 м 2,9 м S 7,3 3,4 0:00,22 стрелорог
19191 Ubuntu 20 0 564,0 м 296,1 м 10,0 м R 56,2 29,8 0:01,92 стрелорог
19198 ubuntu 20 0 97,8 м 34,1 м 2,9 м S 7,7 3,4 0:00,23 стрелорог

URL-адрес заставляет серверный код выполнять некоторую обработку, структурировать данные и затем отправлять обратно:
19208 ubuntu 20 0 97,8 м 34,1 м 2,9 м S 7,7 3,4 0:00,23 стрелорог
19196 ubuntu 20 0 686,4 м 319,3 м 11,2 м R 79,6 32,2 0:05,20 стрелорог
19206 ubuntu 20 0 313,1 м 94,8 м 9,4 м R 16,6 9,6 0:00,74 пушка

Я бы также предложил развернуть простое приложение Django (та же база данных и конфигурация Gunicorn, только одна модель и пара представлений), чтобы увидеть, является ли Gunicorn причиной высокого использования памяти.

Попробую это, но из предыдущего пункта (сравнение потребления памяти для разных URL-адресов) более или менее ясно, что он потребляет одинаковую память даже для простого обращения к сервису отдыха.

как потребление памяти зависит от увеличения рабочих и максимальных запросов? Я спрашиваю об этом, потому что max-request = 1 не будет использоваться в случае производства, и нам придется настроить его и рабочих.

Итак, сколько памяти обычно требуется для небольшого приложения, развернутого с помощью Gunicorn и Nginx (20-30 остальных сервисов, только 4-5 из них выполняют некоторую обработку на сервере, а остальные просто берут данные из базы данных и отправляют обратно пользователю, по меньшей мере 10000 пользователей одновременно) ?

Хорошо, но есть ли способ в python, мы можем попросить освободить неиспользуемую память?

Вам нужно будет написать собственный распределитель памяти с помощью Python C API, но это нетривиальная задача, и я не думаю, что это необходимо.

URL для получения небольших данных:
19181 ubuntu 20 0 553,8 м 281,4 м 10,0 м R 32,6 28,4 0:01,21 стрелорог

Таблицу немного трудно читать. Я предполагаю, что первый столбец - это PID, второй - владелец процесса, но остальное немного сложно догадаться. Не могли бы вы также добавить имена столбцов?

В любом случае увеличение использования памяти с ~90 МБ до ~500 МБ — это уже слишком. Я думаю, что мы бы уже получили много подобных отчетов, если бы уже ввели такую ​​​​огромную утечку памяти :) (Gunicorn 19.7.1 был выпущен более года назад.)

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

Резидент 300 МБ может быть неожиданным, но я не знаю. Это Python и ORM, но я не являюсь активным пользователем Django и сам раньше не профилировал эти вещи.

Для 10 000 пользователей, в зависимости от частоты запросов, вам может понадобиться больше, чем t2.micro. Тем не менее, мы сделаем все возможное, чтобы помочь вам устранить неполадки. Наличие nginx для постановки в очередь запросов к Gunicorn, безусловно, поможет.

Сколько памяти занимает одно и то же приложение при запросе URL-адресов от сервера запуска?

Мы используем t2.micro с 1 ГБ оперативной памяти. Наша установка выглядит следующим образом:

CLIENT           |      AWS SERVER
                 |
                 |                     angular app, static files
                 |                    /
Web App<-------->| <----->ELB<--->nginx
                 |                    \
                 |                     gunicorn <-----> Backend Python Code
                 |

конфиг нгинкс:

server {
listen 80 default_server;

server_name myapp.com www.myapp.com;

charset     utf-8;

# max upload size
# client_max_body_size 75M;
client_max_body_size 0;

# send all non-media requests to the Django server.
location ~ ^/(myapp|admin) {
    proxy_pass http://unix:/home/ubuntu/project/django-ng.sock; # for a file socket
    include proxy_params;
}

location /static  {
    alias /home/ubuntu/project/static/;
}

location / {
    root /home/ubuntu/deploy/angularapp;
    index index.html index.htm;

    try_files $uri $uri/ /index.html;
}
}

конфиг пушкикорна:

description "Gunicorn application server handling myproject"

start on runlevel [2345]
stop on runlevel [!2345]

respawn
setuid ubuntu
setgid www-data
chdir /home/ubuntu/project/

exec ./env/bin/gunicorn --max-requests 1 --workers 3 --bind unix:/home/ubuntu/project/django-ng.sock config.wsgi:application

Сколько памяти занимает одно и то же приложение при запросе URL-адресов от сервера запуска?

Использование «python3 manage.py runserver» на локальном компьютере:

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
Запустить приложение:
1158 пратап 20 0 900,4 м 260,8 м 24,5 м S 0,0 3,2 1:52,17 python3
1156 пратап 20 0 80,9 м 30,8 м 30,2 м S 0,0 0,4 0:00,50 питон3
1158 пратап 20 0 900,4 м 260,8 м 24,5 м S 0,0 3,2 1:52,17 python3
1158 пратап 20 0 900,4 м 263,7 м 24,9 м S 37,0 3,3 1:53,28 питон3

Сначала зайдите в веб-приложение, чтобы выполнить некоторую обработку:
1158 пратап 20 0 913,4 м 294,0 м 25,0 м R 106,6 3,6 1:56,48 питон3
1158 пратап 20 0 935,9 м 345,1 м 25,0 м S 109,6 4,3 1:59,77 питон3
1158 пратап 20 0 938,9 м 349,2 м 25,0 м S 26,6 4,3 2:00,57 питон3
1158 пратап 20 0 938,9 м 349,2 м 25,0 м S 14,3 4,3 2:01,00 питон3
1158 пратап 20 0 938,9 м 349,2 м 25,0 м S 10,0 4,3 2:04,00 питон3
1158 пратап 20 0 938,9 м 349,2 м 25,0 м S 8,0 4,3 2:04,24 питон3
1156 пратап 20 0 80,9 м 30,8 м 30,2 м S 0,0 0,4 0:00,50 питон3
1158 пратап 20 0 938,9 м 349,2 м 25,0 м S 10,3 4,3 2:04,55 питон3
1156 пратап 20 0 80,9 м 30,8 м 30,2 м S 0,0 0,4 0:00,50 питон3
1158 пратап 20 0 938,9 м 349,2 м 25,0 м S 11,0 4,3 2:04,88 питон3
1158 пратап 20 0 938,9 м 349,2 м 25,0 м S 7,7 4,3 2:05,11 питон3

Второе веб-приложение Access для обработки:
1158 пратап 20 0 940,4 м 351,0 м 25,0 м R 8,3 4,3 2:14,01 питон3
1158 пратап 20 0 940,4 м 351,0 м 25,0 м S 6,0 4,3 2:14,19 питон3
1158 пратап 20 0 940,4 м 351,0 м 25,0 м S 10,0 4,3 2:14,49 питон3
1158 пратап 20 0 940,4 м 351,0 м 25,0 м S 9,7 4,3 2:14,78 питон3
1156 пратап 20 0 80,9 м 30,8 м 30,2 м S 0,0 0,4 0:00,50 питон3
1158 пратап 20 0 940,4 м 351,0 м 25,0 м S 5,7 4,3 2:14,95 питон3
1156 пратап 20 0 80,9 м 30,8 м 30,2 м S 0,0 0,4 0:00,50 питон3
1158 пратап 20 0 940,4 м 351,0 м 25,0 м S 9,0 4,3 2:15,22 питон3
1158 пратап 20 0 940,4 м 351,0 м 25,0 м S 9,7 4,3 2:15,51 питон3
1158 пратап 20 0 940,4 м 351,0 м 25,0 м S 9,3 4,3 2:15,79 питон3

Третье веб-приложение Access для обработки:
1158 пратап 20 0 942,4 м 353,7 м 25,0 м S 47,3 4,4 2:17,21 питон3
1158 пратап 20 0 942,4 м 353,7 м 25,0 м S 9,3 4,4 2:17,49 питон3
1158 пратап 20 0 942,4 м 353,7 м 25,0 м S 9,7 4,4 2:17,78 питон3
1158 пратап 20 0 942,4 м 353,7 м 25,0 м R 8,3 4,4 2:18,03 питон3
1158 пратап 20 0 942,4 м 353,7 м 25,0 м S 7,3 4,4 2:18,25 питон3
1158 пратап 20 0 942,4 м 353,7 м 25,0 м R 11,0 4,4 2:19,93 питон3
1158 пратап 20 0 942,4 м 355,1 м 25,0 м S 26,3 4,4 2:20,72 питон3
1158 пратап 20 0 943,7 м 355,4 м 25,0 м S 62,3 4,4 2:22,59 питон3

Сравнивая эти измерения с более ранним комментарием со статистикой памяти Gunicorn, кажется, что здесь нет проблем с Gunicorn. Я неправильно читаю?

@tilgovi В настоящее время я работаю над аналогичной проблемой, и я хотел бы добавить свои выводы на случай, если это может помочь.
У меня 2 ГБ ОЗУ Ubuntu16 VM и запущено веб-приложение Python3, Flask. Поскольку я использовал некоторые библиотеки NLP, начальное использование памяти было высоким.
Вы можете увидеть график использования памяти за последние 30 дней ниже. На самом деле это началось 33%, 3 месяца назад и до сих пор продолжает увеличиваться (вчера я обновился до последней версии gunicorn и других, поэтому график то вверх, то вниз.)
Рабочие установлены на 2.
Я не могу точно сказать, что это вызвано единорогом, но, поскольку я развертываю каждые несколько дней и перезапускаю службу и время от времени перезагружаю виртуальную машину, я ожидаю, что все должно снова начаться примерно с %33 (если это вызвано моим кодом или каким-либо пакетом). Но он продолжает там, где он оставил.

Поэтому я предполагаю, что что-то кэширует вещи и не оставляет их при перезагрузке/перезапуске.

Есть ли какой-либо метод, который я могу отслеживать, что вызывает увеличение памяти под пушкой, поскольку я вижу только 60% памяти, потребляемой пушкой.

image

@tilgovi мы рассмотрели детали и похоже, что результаты использования памяти gunicorn и runserver нельзя сравнивать, потому что мы настроили gunicorn для max-requests 1, который будет перезапускать worker после каждого запроса, поэтому мы действительно не сможем сказать, есть ли память увеличить или нет для последующих вызовов службы отдыха.

Поэтому установите max-request на 100, worker на 3 и повторите наш эксперимент. В режиме ожидания использование памяти gunicorn в порядке:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
25678 Ubuntu 20 0 644632 34868 10824 S 0,0 26,6 0:02,94 пушка
25680 ubuntu 20 0 100136 34876 2992 S 0,0 3,4 0:00,23 стрелорог
25677 ubuntu 20 0 100132 34868 2992 S 0,0 3,4 0:00,24 пушка
25673 ubuntu 20 0 64836 18368 3948 S 0,0 1,8 0:00,17 стрелорог

Но мы используем веб-приложение, тогда рабочий процесс потребляет больше памяти (возможно, для структуры данных python и т. д.), и после обслуживания запроса он не возвращается обратно (возможно, потому, что Python имеет свой собственный распределитель памяти и не возвращает ранее выделенные блоки памяти ОС). но будет использовать эту память для дальнейших запросов службы отдыха) до нормального потребления памяти 34868:

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
25678 ubuntu 20 0 644632 270432 10824 S 0,0 26,6 0:02,94 стрелорог
25680 ubuntu 20 0 100136 34876 2992 S 0,0 3,4 0:00,23 стрелорог
25677 ubuntu 20 0 100132 34868 2992 S 0,0 3,4 0:00,24 пушка
25673 ubuntu 20 0 64836 18368 3948 S 0,0 1,8 0:00,17 стрелорог

но когда вы начинаете использовать веб-приложение, рабочие выбираются случайным образом, и когда третий рабочий процесс выбирается для обслуживания запроса (после того, как другие два рабочих процесса уже обслужили и удерживают по 270428 КБ памяти каждый), наша система пытается выделить память, которая недоступна. достаточно, и рабочий вылетает и перезапускается. Таким образом, похоже, что мы можем правильно отладить потребление памяти только в том случае, если у нас достаточно памяти, доступной для приложения достаточное количество раз без сбоев рабочих процессов и перезапуска. Только тогда мы можем определить, увеличивается ли используемая память с течением времени (утечка) или возвращается к первому случаю, когда рабочий процесс потребляет память для себя и для выделения python (что является нормальной ситуацией).

Worker аварийно завершает работу, не завершив запрос из-за нехватки доступной памяти:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
25677 ubuntu 20 0 636968 331944 4 R 5,2 32,7 0:02,30 стрелорог
25678 Ubuntu 20 0 644632 259684 0 S 0,0 25,6 0:02,95 стрелорог
25680 ubuntu 20 0 644636 259668 0 S 0,3 25,6 0:02,97 стрелорог
1094 mysql 20 0 689704 49144 0 S 0,0 4,8 16:22,92 mysqld
25673 убунту 20 0 64836 14428 0 S 0,6 1,4 0:00,23 стрелорог

Простите меня, я все еще не совсем понимаю. Похоже, что Gunicorn использует ~ 300 МБ. Единственная разница с максимальными запросами заключается в том, что у вас, скорее всего, будут все три воркера, потребляющие ~ 300 МБ каждый, а не только тот, который в данный момент обрабатывает запрос.

С другой стороны, runserver также использует ~ 300 МБ на процесс.

Кажется, что ваш экземпляр недостаточно велик для запуска трех рабочих процессов, и не имеет значения, используете ли вы runserver или gunicorn.

Если вы хотите обрабатывать больше одновременных запросов, вам нужно использовать асинхронный рабочий тип, а не запускать несколько рабочих процессов.

Есть ли что-то еще, что мне не хватает?

Я думаю, что вы абсолютно правы, и ничего не упущено. На самом деле проблема заключалась в том, что в документации Gunicro пользователю предлагалось количество рабочих процессов как 2*N + 1, а поскольку у нас было одно ядро, мы использовали 3 рабочих процесса.

Теперь ничего не упоминается о том, как используются эти воркеры. Похоже, они планируются ОС, и вы никогда не знаете, какой воркер будет обрабатывать входящий запрос. Итак, изначально у нас была ограниченная память, из которой nginx и другие системные процессы занимали некоторую часть, тогда как остальная память (~ 800 МБ) должна была использоваться рабочими процессами. Поскольку мы настроили для 3 рабочих процессов, предполагая, что каждый рабочий процесс занимает 300 МБ, тогда все 3 вместе будут потреблять 900 МБ, которые недоступны, поэтому, когда третий рабочий процесс (о котором вы никогда не знаете, потому что он соответствует планированию ОС) обрабатывает запрос (после другие 2 воркера уже обработаны и потребляют в общей сложности 600 МБ), тогда в системе не хватает памяти, и воркер дает сбой. Это произошло случайно, поэтому мы настроили max-request как 1, который перезапускал worker после каждого запроса и освобождал всю память, выделенную для нашего приложения Python. Таким образом, крах воркера был преодолен, но система стала тормозить, и мы думали, что это воркер, который внезапно занимает огромную память и замедляет систему, и мы даже не могли его отладить, так как каждый раз воркер перезапускался. Чтобы отладить его больше, нам нужно было иметь max-request, достаточно большой, чтобы обслуживать больше запросов без перезапуска рабочего процесса, но это было невозможно, потому что, если мы разрешаем больше запросов с 3 рабочими процессами (каждый может занимать ~ 300 МБ) в системе 1 ГБ, рабочий процесс был сбой, и мы получали из памяти.

Но хотя мы сделали количество рабочих равным 1, система ведет себя более или менее как runserver. Итак, теперь у нас не заканчивается память, и система также работает быстро.

Итак, мы узнали, что общее правило создания 2*N+1 воркеров — это всего лишь расплывчатая логика, поскольку вам также нужно учитывать память.

Предположим, что каждый рабочий процесс gunicorn занимает «W» памяти, а общая системная память равна «T» и имеет N = 1 ядро.

Итак, согласно предложению минимальное количество рабочих = 2 * 1 + 1 = 3.

Теперь предположим, что ваше приложение занимает память «А».

Таким образом, общая память требуется только для одного работника, обрабатывающего все запросы R = W * 3 + A.

Итак, пока T больше, чем R, все в порядке, но проблема возникает, когда предположим, что операционная система планирует, чтобы другие рабочие процессы обслуживали больше запросов, тогда каждый рабочий процесс потребляет не менее W + A памяти. Таким образом, на самом деле системная память, необходимая для gunicorn с 3 рабочими процессами, должна быть больше, чем (W + A) * 3, чтобы избежать случайных зависаний, случайных ответов без ответов или случайных ответов на неправильные запросы (например, nginx используется в качестве обратного прокси-сервера, тогда он не получит никакого ответа если рабочий процесс gunicorn падает из-за нехватки памяти, и, в свою очередь, nginx ответит сообщением о неверном запросе)

Поэтому нам нужно быть осторожными при настройке пушки и учитывать как количество ядер, так и количество памяти.

Я считаю, что документация Gunicorn на http://docs.gunicorn.org/en/stable/settings.html
следует также упомянуть о потреблении памяти при настройке рабочих процессов.

Логика не такая расплывчатая ;) Наличие 2*ядер + 1 позволяет хорошо распределять нагрузку между воркерами. Верно и то, что каждый рабочий процесс изолирован и будет загружать приложение независимо, а затем потреблять часть памяти.

Если вы хотите уменьшить размер воркеров на ограниченной машине, вы можете использовать параметр --preload , который предварительно загрузит код приложения и разделит его между воркерами.

также хороший момент, у нас должна быть часть о памяти на этой странице дизайна.

gunicorn определенно ест много памяти, чем должен, недавно я переключился на uwsgi, чтобы сохранить потери памяти.

@ tyan4g gunicorn сам по себе не использует много памяти, не буферизируется и занимает довольно мало памяти для приложения Python. То, что использует оперативную память, - это, как правило, приложение и его использование. Все рабочие процессы изолированы, и по умолчанию память не используется совместно. uwsgi имеет аналогичный подход, поэтому он не должен сильно влиять на память. Обратите внимание, что использование gthread или любого другого асинхронного рабочего процесса позволяет при необходимости уменьшить количество рабочих процессов.

Я также обнаружил, что рабочий процесс внезапно увеличился. Со временем мы встречаемся с утечкой памяти. Затем я настроил gunicorn с максимальным запросом, после чего проблема была решена. Я хочу знать возможную причину, по которой я столкнулся с утечкой памяти, когда запускаю пушку без параметров max_request. Я использовал версию gunicorn 19.7.0.

@benoitc Можете ли вы помочь мне с ходом мыслей?

@v-wiil вам, вероятно, придется исследовать это самостоятельно и открыть новую проблему, если вы считаете, что в Gunicorn есть утечка.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги