У меня есть собственное приложение Django, которое перестает отвечать примерно каждые 5000 запросов. В журналах apache я вижу следующее:
Apr 13 11:45:07 www3 apache2[27590]: **successful view render here**
...
Apr 13 11:47:11 www3 apache2[24032]: [error] server is within MinSpareThreads of MaxClients, consider raising the MaxClients setting
Apr 13 11:47:43 www3 apache2[24032]: [error] server reached MaxClients setting, consider raising the MaxClients setting
...
Apr 13 11:50:34 www3 apache2[27617]: [error] [client 10.177.0.204] Script timed out before returning headers: django.wsgi
(repeated 100 times, exactly)
Я считаю, что использую WSGI 2.6 (/usr/lib/apache2/modules/mod_wsgi.so-2.6) со следующей конфигурацией:
конфигурация apache
WSGIDaemonProcess site-1 user=django group=django threads=50
WSGIProcessGroup site-1
WSGIScriptAlias / /somepath/django.wsgi
/somepath/django.wsgi
import os, sys
sys.path.append('/home/django')
os.environ['DJANGO_SETTINGS_MODULE'] = 'myapp.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
Когда это произойдет, я могу убить процесс wsgi, и сервер восстановится.
>ps aux|grep django # process is running as user "django"
django 27590 5.3 17.4 908024 178760 ? Sl Apr12 76:09 /usr/sbin/apache2 -k start
>kill -9 27590
Это заставляет меня думать, что проблема в известная проблема:
deadlock-timeout = sss (2.0+)
Определяет максимальное количество секунд, которое может пройти, прежде чем процесс демона будет остановлен и перезапущен после обнаружения потенциальной взаимоблокировки Python GIL. По умолчанию 300 секунд. Эта опция существует для борьбы с проблемой зависания процесса демона в результате модуля расширения Python C, который не освобождает должным образом Python GIL при входе в блокирующую или длительную операцию.
Однако я не уверен, почему это условие не очищается автоматически. Я действительно вижу, что тайм-аут сценария происходит ровно через 5 минут после последней успешной рендеринга страницы, поэтому срабатывает таймаут взаимоблокировки. Но на самом деле это не убивает процесс.
Изменить: подробнее
Вы можете попробовать добавить ограничение на количество запросов, после которого процессы демона перезапускаются (до того, как это сделает внешний процесс). Это делается путем добавления maximum-requests
параметр WSGIDaemonProcess
.
Видеть https://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines#Defining_Process_Groups
В качестве альтернативы вы можете узнать, сколько процессов разрешено использовать вашему пользователю django. Вы можете проверить это, открыв оболочку от имени этого пользователя. su - django -s /bin/bash
и проверка вывода ulimit -a
.