Apache / wsgi "Skript läuft ab, bevor Header zurückgegeben werden"

8

Ich habe eine benutzerdefinierte Django-App, die ungefähr alle 5.000 Anfragen nicht mehr reagiert. In den Apache-Protokollen sehe ich Folgendes:

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)

Ich glaube, ich verwende WSGI 2.6 (/usr/lib/apache2/modules/mod_wsgi.so-2.6) mit der folgenden Konfiguration:

Apache-Konfiguration

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()

In diesem Fall kann ich den wsgi-Prozess beenden und der Server wird wiederhergestellt.

>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

Dies lässt mich glauben, dass das Problem ein bekanntes Problem ist :

Deadlock-Timeout = sss (2.0+)

Definiert die maximale Anzahl von Sekunden, die vergehen dürfen, bevor der Dämonprozess heruntergefahren und neu gestartet wird, nachdem ein möglicher Deadlock auf der Python-GIL erkannt wurde. Der Standardwert beträgt 300 Sekunden. Diese Option ist verfügbar, um das Problem des Einfrierens eines Daemon-Prozesses infolge eines Rouge-Python-C-Erweiterungsmoduls zu bekämpfen, das die Python-GIL nicht ordnungsgemäß freigibt, wenn ein blockierender oder lang laufender Vorgang ausgeführt wird.

Ich bin mir jedoch nicht sicher, warum dieser Zustand nicht automatisch gelöscht wird. Ich sehe, dass das Skript-Timeout genau 5 Minuten nach dem letzten erfolgreichen Rendern der Seite auftritt, sodass das Deadlock-Timeout ausgelöst wird. Aber es beendet den Prozess nicht wirklich.

Bearbeiten: mehr Infos

  • Apache - Version 2.2, mit der worker MPM
  • wsgi version 2.8
  • SELinux NICHT installiert l
  • XML-Paket wird selten verwendet
  • Ubuntu 10.04
Chase Seibert
quelle
1
Zu Ihrer
Chase Seibert

Antworten:

0

Sie können versuchen, ein Limit von Anforderungen hinzuzufügen, nach denen die Daemon-Prozesse wiederverwendet werden (bevor dies von einem externen Prozess ausgeführt wird). Dies erfolgt durch Hinzufügen des maximum-requestsParameters von WSGIDaemonProcess.

Siehe https://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines#Defining_Process_Groups

Alternativ können Sie untersuchen, wie viele Prozesse Ihr Django-Benutzer ausführen darf. Sie können dies überprüfen, indem Sie eine Shell als dieser Benutzer öffnen su - django -s /bin/bashund die Ausgabe von überprüfen ulimit -a.

wkoot
quelle
Mein Verständnis ist, dass maximum-requestsdies im Produktionscode vermieden werden sollte. Siehe diesen Thread: groups.google.com/forum/#!msg/modwsgi/KzNd5xGQjrM/i5Dz7TBePNQJ
dbn
Persönlich würde ich es sowieso vermeiden, mod-wsgi in der Produktion zu verwenden. Es gibt schönere Optionen in uWSGI, wie "billiger": uwsgi-docs.readthedocs.org/en/latest/Cheaper.html
wkoot