2017-10-27 4 views
0

Ich habe eine Django 1.11-Seite von Apache 2.4.18 + ModWSGI auf Ubuntu 16 und es hängt auf unbestimmte Zeit. Was ist seltsam ist, dass, wenn ich Apache aufhöre, nur dann die Anfrage zurückgibt, die die Seite perfekt rendert, was impliziert, dass Django die Anfrage korrekt zurückgibt, aber etwas verhindert, dass Apache die Daten sendet.Django + Apache + ModWSGI hängt unbestimmt

Mein Apache site.conf:

<VirtualHost *:80> 
    ServerName www.mysite.com 
    ServerAlias www.mysite.com 
    ServerAdmin [email protected] 
    DocumentRoot /usr/local/mysite 

    AllowEncodedSlashes On 

    Alias /media/ /usr/local/mysite/media/ 
    Alias /static/ /usr/local/mysite/static/ 

    <Directory /usr/local/mysite> 
     Options Indexes FollowSymLinks MultiViews 
     AllowOverride None 
     Order allow,deny 
     Allow from all 
     # New directive needed in Apache 2.4.3. 
     Require all granted 
    </Directory> 

    <Directory /> 
     Options FollowSymLinks 
     AllowOverride None 
    </Directory> 

    LogLevel debug 
    ErrorLog ${APACHE_LOG_DIR}/mysite-error.log 
    CustomLog ${APACHE_LOG_DIR}/mysite-access.log combined 

    # Stop GIL deadlocks from crashing Python/Modwsgi due to Python C-extensions? 
    # Without this, you may get a "Premature end of script" error. 
    # https://code.google.com/p/modwsgi/wiki/ApplicationIssues#Python_Simplified_GIL_State_API 
    WSGIApplicationGroup %{GLOBAL} 

    WSGIDaemonProcess www.mysite.com python-path=/usr/local/mysite/.env/lib/python2.7/site-packages processes=1 display-name=%{GROUP} user=www-data group=www-data 
    WSGIProcessGroup www.mysite.com 
    WSGIScriptAlias//usr/local/mysite/wsgi/mysite.wsgi 

    <Directory /usr/local/mysite/wsgi> 
     Order allow,deny 
     Allow from all 
    </Directory> 

</VirtualHost> 

Meine Django wsgi:

import os 
import time 
import traceback 
import signal 
import sys 

from django.core.wsgi import get_wsgi_application 

os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings.settings' 
os.environ['CELERY_LOADER'] = 'django' 

sys.path.append(os.path.join(os.path.realpath(os.path.dirname(__file__)), '../src')) 
sys.path.append(os.path.join(os.path.realpath(os.path.dirname(__file__)), '../src/mysite')) 

try: 
    application = get_wsgi_application() 
    print 'WSGI without exception' 
except Exception: 
    print 'handling WSGI exception' 
    # Error loading applications 
    if 'mod_wsgi' in sys.modules: 
     traceback.print_exc() 
     os.kill(os.getpid(), signal.SIGINT) 
     time.sleep(2.5) 

Das einzige, was von Interesse an meinem Apache-Logs sind ein paar Zeilen wie:

[Fri Oct 27 02:37:08.079977 2017] [wsgi:error] [pid 14053:tid 139644805011200] [client 10.182.122.159:45695] Timeout when reading response headers from daemon process 'www.mysite.com': /usr/local/mysite/wsgi/mysite.wsgi 

Offensichtlich scheint etwas nicht das richtige Signal zu bekommen, was dazu führt, dass es bis zu einer Zeitüberschreitung wartet, aber ich kann es nicht verstehen aus, was die Ursache ist. Ich habe versucht, meine Apache-Konfiguration zu refactoring und deaktivieren Teile meiner Django-App, die Zeitlimit sein könnte, aber nichts hat funktioniert. Wie diagnostiziere ich das?

Antwort

0

Höchstwahrscheinlich werden Ihre Anfragen blockiert und kehren nie zurück. Nichts mit Signalen zu tun, oder Apaches eigene Verwendung von Signalen zumindest. Das Abschaltsignal unterbricht möglicherweise einen Systemanruf, bei dem Ihre Anfrage blockiert ist.

-WSGIDaemonProcess Richtlinie Fügen Sie die Option:

request-timeout=60 

und die Protokolle zu überwachen, um zu sehen, ob mod_wsgi Daemon-Prozess aufgrund Anfrage Timeouts Neustart erhalten.

Da Sie einen einzelnen Prozess mit dem Standardwert 15 Threads verwenden, wird die Verarbeitung von Anforderungstimeouts als Durchschnitt für alle Anforderungshandler verwendet. Wenn nur ein einziger Anforderungshandler unbegrenzt blockiert, dauert es bis zu 15 Minuten für erzwungen Neustart des Prozesses. Wenn mehrere Anforderungen blockiert werden, ist dies schneller.

Ich nehme an, dass 60 Sekunden mehr ist als Sie erwarten, dass Sie Anforderungen für ausführen. Setzen Sie es niedriger, wenn Anfragen immer schneller bearbeitet werden sollen.

Sie brauchen auch nicht try/except/kill Zeug in Ihrer WSGI-Skriptdatei. Statt dass WSGIDaemonProcess die Option hinzufügen:

startup-timeout=15 
+0

Der try/except/Tötungs Sachen notwendig ist, sonst ModWSGI verschleiert Python Ausnahmen von den Protokollen. Ich habe gelernt, dass ein Tipp von einem anderen SO auf die Frage antwortet: "Warum kann ich keine Django-Ausnahmen in meinen Apache-Logs sehen?" – Cerin

+0

Außerdem scheint 'startup-timeout' keine gültige Apache-Option zu sein. Damit lehnt Apache das Laden meiner Konfiguration ab. – Cerin

+0

Warum schlagen Sie vor, 'request-timeout = 60' zu verwenden? Ich weiß bereits, dass meine Anforderungen zeitlimitiert sind, wie aus dem Protokolleintrag hervorgeht, den ich gepostet habe. Ich versuche die Ursache für die Zeitüberschreitung zu finden. – Cerin