Назад | Перейти на главную страницу

Apache / wsgi «Время ожидания сценария истекло перед возвратом заголовков»

У меня есть собственное приложение 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.