WSGI: получены усеченные или чрезмерно длинные заголовки ответа от фонового процесса

Вопрос или проблема

Конфигурация системы: Apache2, Django 1.10, Python 3, Ubuntu 16.04 LTS

Django debug=True.


/var/log/apache2/error.log

[52:53.057967] [wsgi:error] [pid 4303] [client 1.1.1.22:24409] Timeout when reading response headers from daemon process 'example.org': /home/user/dir/project/main_app/wsgi.py
[52:58.466726] [wsgi:error] [pid 4305] [client 1.1.1.10:9787] Truncated or oversized response headers received from daemon process 'example.org': /home/user/dir/project/main_app/wsgi.py
[52:58.466729] [wsgi:error] [pid 4304] [client 1.1.1.4:18417] Truncated or oversized response headers received from daemon process 'example.org': /home/user/dir/project/main_app/wsgi.py
[52:58.466726] [wsgi:error] [pid 4307] [client 1.1.1.22:35116] Truncated or oversized response headers received from daemon process 'example.org': /home/user/dir/project/main_app/wsgi.py
[52:58.466756] [wsgi:error] [pid 4306] [client 1.1.1.22:19242] Truncated or oversized response headers received from daemon process 'example.org': /home/user/dir/project/main_app/wsgi.py
[52:58.467164] [wsgi:error] [pid 4336] [client 1.1.1.4:34187] Truncated or oversized response headers received from daemon process 'example.org': /home/user/dir/project/main_app/wsgi.py
[52:58.467212] [wsgi:error] [pid 4342] [client 1.1.1.22:28212] Truncated or oversized response headers received from daemon process 'example.org': /home/user/dir/project/main_app/wsgi.py, referer: http://example.org/
[52:58.467282] [wsgi:error] [pid 4331] [client 1.1.1.22:31045] Truncated or oversized response headers received from daemon process 'example.org': /home/user/dir/project/main_app/wsgi.py
[52:58.467426] [wsgi:error] [pid 4341] [client 1.1.1.70:22784] Truncated or oversized response headers received from daemon process 'example.org': /home/user/dir/project/main_app/wsgi.py, referer: http://example.org/

Я не знаю причину ошибки, но я сузил её до процесса Django wsgi, поскольку сервер корректно обслуживает статические файлы.

Хотя Cloudflare иногда показывает 502 : Bad Gateway Error, сам сервер показывает 500 : Internal Server Error.

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


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

Примечание: сервер работал нормально ранее. Я сделал некоторые изменения* (которые были возвращены обратно как есть); оболочка Django работает нормально.

Изменения*

  1. Установлены django-pandas, django-model-utils, numpy, scikit-learn
  2. Программа, использующая указанные библиотеки. (Это изменение было возвращено к оригиналу)

В других аналогичных вопросах проблема возникает при загрузке большого файла.

Причиной проблемы был numpy.

Известно, что модули расширения C для Python, такие как numpy, могут вызывать тайм-ауты при использовании под mod_wsgi.

Источник: Ответ Sean F на Timeout when reading response headers from daemon process

Подобный вопрос, который я не нашел при первоначальном поиске, был отвечен и объяснен автором mod_wsgi

Некоторые сторонние пакеты для Python, использующие модули расширения C, и это включает scipy и numpy, будут работать только в основном интерпретаторе Python и не могут быть использованы в подинтерпретаторах, как это по умолчанию использует mod_wsgi. Результатом могут быть блокировки потоков, некорректное поведение или сбои процессов.

Источник: Ответ Graham Dumpleton на Non-responsive apache + mod_wsgi after installing scipy

Решение

Добавьте следующую строку в ваш httpd.conf. В моем случае файл был /etc/apache2/apache2.conf.

WSGIApplicationGroup %{GLOBAL}

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

Если это проблема, один из способов решения – переключить тип MPM Apache. Тип prefork не использует потоки, поэтому, если проблема заключается в сбое numpy из-за неправильного использования потоков, это должно ее решить. Типы worker и event используют меньше памяти, но также используют потоки, поэтому могут столкнуться с этой ошибкой.

Чтобы определить, какой тип вы используете в данный момент, выполните команду:

apachectl -V | grep -i mpm

Если вы видите Server MPM: prefork, то вы уже используете prefork, что означает, что причина ошибки может быть в чем-то другом. Если указано “worker” или “event”, то вы можете переключиться на prefork, выполнив следующие команды:

sudo a2dismod mpm_event
sudo a2dismod mpm_worker
sudo a2enmod mpm_prefork
sudo service apache2 restart

Обратите внимание, что основным недостатком prefork является то, что, поскольку он не использует потоки, он потребляет больше памяти.

Редактировать: я столкнулся с этой ошибкой по другим причинам позже. Совсем недавно проблема была вызвана ошибкой в ​​системном пакете mod-wsgi, предварительно скомпилированном Ubuntu, а также ошибкой в ​​пакете Python psycopg2.

Решением было переключение с системного mod-wsgi на пакет Python, а также переключение на пакет psycopg2-binary:

sudo apt purge libapache2-mod-wsgi*
sudo apt install apache2-dev
pip uninstall psycopg2
pip install mod_wsgi psycopg2-binary

Мне также пришлось обновить файл конфигурации сайта apache, добавив в начало:

LoadModule wsgi_module /usr/local/myproject/.env/lib/python2.7/site-packages/mod_wsgi/server/mod_wsgi-py27.so

А также изменить строку WSGIDaemonProcess, чтобы использовать python-home вместо python-path, следующим образом:

WSGIDaemonProcess myproject python-home=/usr/local/myproject/.env processes=5 threads=15 display-name=%{GROUP} user=www-data group=www-data

Я столкнулся с этим как для Python2.7, так и для Python3.7, и решение было тем же, но путь к mod_wsgi.so менялся.

Я получил аналогичную ошибку при попытке запустить opencv, используя mod_wsgi и apache. Я думаю, что проблема, вероятно, заключалась в множественных потоках с базисным кодом C, пытающихся получить доступ к GIL и неудачных попытках.

Я решил её, установив threads=1 и processes=32 (в моем случае это было уместно) в директиве WSGIDaemonProcess.

PS: Поздно к вечеринке, но подумал, что это может помочь кому-то.

В моем случае я должен был изменить строку WSGIDaemonProcess с:

WSGIDaemonProcess wsgi processes=2 threads=4 display-name=%{GROUP} \
  python-path=/var/www/appname:/var/www/appname/venv/lib/python2.7/site-packages user=wsgi group=wsgi \
  home=/var/www/appname

на:

WSGIDaemonProcess appname user=wsgi group=wsgi processes=2 threads=4 display-name=%{GROUP} home=/var/www/appname

В моем случае проблема была в pymongo и PHP. Как описано в этом вопросе на GitHub https://github.com/GrahamDumpleton/mod_wsgi/issues/351:

Если PHP загружает клиент для MongoDB, это может [создать конфликт]. (…) PHP часто предварительно загружает все расширения. Не имеет значения, использует это хост-приложение или нет.

Способ, которым я это решил:

  1. Я запустил своё flask-приложение с помощью mod_wsgi-express: mod_wsgi-express start-server api.wsgi --user=www-data --group=www-data --host=0.0.0.0 --port=8443.
  2. Затем, в своем httpd.conf, я перенаправил весь трафик на alias моего flask-приложения с помощью:
SSLEngine on
SSLProxyEngine On
ProxyPass /api http://localhost:8443/
ProxyPassReverse /api http://localhost:8443/

Краткое содержание: Убедитесь, что вы используете реальную базу данных (не SQLite) в любой не локальной среде разработки.

Эта ошибка также может возникнуть, если вы пытаетесь использовать SQLite на реальном сервере (т. е. среда разработки, тестирования или производства).

Похоже, что Apache с mod_wsgi действительно не может работать с SQLite.

У меня было несколько сайтов, которые практически не использовали базу данных; все мои файлы моделей были пустыми, поэтому я думал, что можно не беспокоиться об настройке MySQL или PostgreSQL, но я ошибался.

Сам Django использует базу данных, поэтому даже если вы не используете свои собственные модели, вы, вероятно, столкнетесь с этими ошибками, если попробуете использовать стандартную базу данных SQLite на реальном сервере.

Ответ или решение

Ошибка "Truncated or oversized response headers received from daemon process" часто встречается при использовании Apache с модулем mod_wsgi для запуска приложений, написанных на Python, таких как Django. Основной причиной появления данной ошибки является слишком большие или обрезанные заголовки ответа, которые возвращает сервер в процессе обработки HTTP-запросов. Давайте подробнее разберём причины возникновения подобной ошибки и предложим способы её решения.

Теория

Проблематика: Основная проблема заключается в том, что некоторые сторонние библиотеки на Python, использующие C-расширения, могут сталкиваться с ошибками, когда запускаются в потоках, отличающихся от основного интерпретатора Python. Это особенно актуально для таких библиотек, как numpy и scipy, которые могут приводить к падению процессов или зависанию потоков, если они используются в подинтерпретаторах, создаваемых mod_wsgi.

Возможные причины:

  1. Использование C-расширений: Библиотеки, такие как numpy и scipy, могут корректно работать только в основном интерпретаторе Python из-за их особенностей работы с глобальной блокировкой интерпретатора (GIL).
  2. Неправильная конфигурация Apache и mod_wsgi: Использование неправильных параметров конфигурации для Apache, таких как тип модуля многопроцессора (MPM), может вызывать ошибки в сочетании с поточными библиотеками.
  3. Ограничения памяти и ресурсов: Использование многопоточной обработки может привести к увеличенному расходу памяти, что негативно сказывается на работе сервера.

Пример

В данной проблеме, описанной выше, сервер Apache с модулем mod_wsgi периодически выдаёт ошибки 502 и 500, принимая в виде заголовков HTTP-ответа обрезанную или слишком большую информацию. Причина может заключаться в установленной библиотеке numpy, которая не всегда устойчива к работе с потоками, используемыми Apache.

Применение

  1. Настройка конфигурации Apache:

    • Отключите многопоточные модули Apache, такие как mpm_event или mpm_worker, и используйте mpm_prefork.
      sudo a2dismod mpm_event
      sudo a2dismod mpm_worker
      sudo a2enmod mpm_prefork
      sudo service apache2 restart
    • Измените конфигурацию WSGI, добавив WSGIApplicationGroup %{GLOBAL} в файл конфигурации Apache (обычно /etc/apache2/apache2.conf). Это заставит все приложения работать в основном интерпретаторе Python, избегая использования подинтерпретаторов.
  2. Оптимизация использования модулей:

    • Убедитесь, что используемые модули и библиотеки поддерживают многопоточную обработку (если она необходима). Если библиотека вызывает проблемы, возможно стоит рассмотреть аналогичные решения, не использующие C-расширения.
  3. Обновление среды работы:

    • Рассмотрите обновление mod_wsgi с системного пакета до версии, установленной через pip. Это может решить проблемы, вызванные устаревшими библиотеками или багами в предустановленных версиях.
      sudo apt purge libapache2-mod-wsgi*
      sudo apt install apache2-dev
      pip uninstall psycopg2
      pip install mod_wsgi psycopg2-binary
  4. Изменение базы данных:

    • Избегайте использования SQLite в производственной среде. SQLite плохо масштабируется, и может вызывать ошибки в Apache/mod_wsgi конфигурациях. Переключите базу данных на более надежные решения, такие как PostgreSQL или MySQL.
  5. Логирование и мониторинг:

    • Настройте журналирование, чтобы лучше отслеживать, в какой момент происходит сбой и какое именно приложение или запрос вызывает ошибку. Это поможет оперативно реагировать на сбои и принимать более обоснованные решения.

Внедрение таких подходов позволит вам минимизировать риск возникновения ошибок при работе с Python-приложениями на базе Apache и mod_wsgi. Путём корректной настройки конфигурации и модернизации используемых библиотек ваша система будет более устойчивой и производительной.

Оцените материал
Добавить комментарий

Капча загружается...