Джанго / Apache заморозить с помощью mod_wsgi - PullRequest
3 голосов
/ 23 сентября 2011

У меня есть приложение Django, которое работает за 2-мя серверами mod_wsgi / Apache с балансировкой нагрузки за Nginx (статические файлы, обратный прокси / баланс нагрузки).

Каждые несколько дней мой сайт перестает отвечать на запросы.Я предполагаю, что группа клиентов запрашивает блокирующие URL-адреса.

Вот мой конфиг

WSGIDaemonProcess web1 user=web1 group=web1 processes=8 threads=15 maximum-requests=500 python-path=/home/web1/django_env/lib/python2.6/site-packages display-name=%{GROUP}
WSGIProcessGroup web1
WSGIScriptAlias / /home/web1/django/wsgi/wsgi_handler.py

Я пытался экспериментировать только с использованием одного потока и нескольких процессов, ибольше потоков и один процесс.Практически все, что я пробую, рано или поздно приводит к загрузке страниц по тайм-ауту.

Есть предложения, что можно попробовать?Я готов попробовать другие варианты развертывания, если это решит проблему.

Кроме того, есть ли лучший способ мониторинга mod_wsgi, кроме модуля состояния Apache?Я нажимал:

 curl http://localhost:8080/server-status?auto

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

ПРИМЕЧАНИЕ. Некоторые из этих запросов относятся к веб-службе REST, которую я размещаю для приложения.Имеет ли смысл каким-то образом ограничивать местоположение URL-адреса через Nginx?

Ответы [ 3 ]

3 голосов
/ 24 сентября 2011

Использование:

http://code.google.com/p/modwsgi/wiki/DebuggingTechniques#Extracting_Python_Stack_Traces

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

В качестве отказоустойчивого устройства вы можете добавить параметр:

inactivity-timeout=600

в директиву WSGIDaemonProcess.

Что это сделает, перезапустит процесс в режиме демона, если он неактивен в течение 10 минут.

К сожалению, в настоящее время это происходит в двух сценариях.

Во-первых, когда в течение 10 минут вообще не было никаких запросов, процесс будет перезапущен.

Второй, и тот, который вы хотите запустить, - это если все потоки запросов заблокированы.и никто из них не прочитал никаких входных данных из wsgi.input и не дал никакого содержимого ответа, через 10 минут процесс снова будет перезапущен автоматически.

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

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

Что я должен сделать, так это добавитьновый параметр заблокированный тайм-аут, который специально проверяет все запросы, блокируемые на определенный период, поэтому отделяет его от перезапусков из-за отсутствия запросов вообще.Это сделало бы это более гибким, так как перезапуск из-за отсутствия запросов приводит к собственным проблемам с загрузкой приложения снова.

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

Еще одна интересная вещь, которую я могу сделать, - добавить в mod_wsgi материал, чтобы сообщить о таких принудительных перезапусках из-за заблокированных процессов в агент New Relic.Это было бы здорово, если бы вы увидели их в инструменте мониторинга.: -)

0 голосов
/ 28 мая 2014

У нас была похожая проблема на моей работе. Лучшее, что мы могли когда-либо выяснить, это проблемы гонки / тупика с приложением, из-за которых mod_wsgi застрял. Обычно, убивая один или несколько процессов mod_wsgi, можно на некоторое время отсоединить его.

Лучшим решением было перейти на все процессы без потоков. Мы подтвердили с нашими командами разработчиков, что некоторые из библиотек Python, в которые они работали, скорее всего не были поточно-ориентированными.

Попытка:

WSGIDaemonProcess web1 пользователь = группа web1 = процессы web1 = 16 потоков = 1 максимальное количество запросов = 500 python-path = / home / web1 / django_env / lib / python2.6 / site-packages display-name =% {GROUP}

Недостатком является то, что процессы отнимают больше памяти, чем потоки. Следовательно, у нас обычно меньше рабочих (следовательно, 16x1 вместо 8x15). А так как mod_wsgi практически ничего не дает, чтобы сообщать о том, насколько заняты работники, вы SOL, за исключением того, что просто настраиваете, сколько у вас есть.

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

Как и в PHP, не используйте многопоточную реализацию, если вы не уверены, что она безопасна ... это означает ядро ​​(обычно в порядке), фреймворк, ваш собственный код и все, что вы импортируете. :)

0 голосов
/ 23 сентября 2011

Если я правильно понял вашу проблему, вы можете попробовать следующие варианты:

  • убрать выборку URL из цикла запрос / ответ (с использованием, например, сельдерея);
  • увеличить количество потоков (они могут обрабатывать такие блоки лучше, чем процессы, потому что они потребляют меньше памяти);
  • уменьшить таймаут для urllib2.urlopen;
  • попробуйте gevent или eventlet (они волшебным образом решат вашу проблему, но могут внести другие тонкие проблемы)

Я не думаю, что это проблема развертывания, это больше проблема кода, и нет никакой конфигурации apache, решающей ее.

...