2009-10-28 15 views
7

Ich entwickle eine Django-Site. Ich mache alle meine Änderungen am Live-Server, nur weil es einfacher ist. Das Problem ist, hin und wieder scheint es, eine der * .py-Dateien, an denen ich gerade arbeite, zu cachen. Wenn ich häufig auf "Aktualisieren" klicke, wird zwischen einer älteren Version der Seite und einer neueren Version gewechselt.Django + WSGI: Erfrischende Probleme?

Mein Set up ist mehr oder weniger wie das, was in den Django-Tutorials beschrieben ist: http://docs.djangoproject.com/en/dev/howto/deployment/modwsgi/#howto-deployment-modwsgi

Ich vermute, es dies tut, weil es mehrere Instanzen der WSGI-Handler, und je nachdem, welchen Anheizen Handler Wenn die http-Anfrage gesendet wird, kann ich verschiedene Versionen der Seite erhalten. Apache Neustart scheint das Problem zu beheben, aber es ist ärgerlich.

Ich weiß wirklich nicht viel über WSGI oder "MiddleWare" oder irgendwelche dieser Anfrage Handhabung Zeug. Ich komme von einem PHP-Hintergrund, wo alles nur funktioniert :)

Wie auch immer, was ist eine gute Möglichkeit, dieses Problem zu lösen? Ist das Ausführen des WSGI-Handlers "Daemon-Modus", um das Problem zu beheben? Wenn ja, wie bekomme ich es im Daemon-Modus laufen?

Antwort

2

Sie können dieses Problem lösen, indem nicht die Bearbeitung der Code auf dem Live-Server. Ernsthaft, es gibt keine Entschuldigung dafür. Entwickeln Sie lokal mithilfe der Versionskontrolle, und wenn Sie müssen, führen Sie Ihren Server von einem Live-Checkout mit einem Post-Commit-Hook aus, der Ihre neueste Version auscheckt und Apache neu startet.

+1

Ja, aber manchmal verhält sich prod environment anders als der eingebaute dev-Server, also keine Wahl :) – jujule

+0

@jujule: Sie können eine Test-Domain auf dem Prod-Server einrichten, so dass Sie testen können, was Sie lokal entwickeln. Ich kann mir keine Ausreden vorstellen, die die Bearbeitung von Code auf dem Prod-Server rechtfertigen könnten. – shanyu

+0

es ist so viel Arbeit, die Serverumgebung zu replizieren! Auf meinem Server läuft ubuntu/apache2/postgres, und mein Heimcomputer verwendet win7 ... und ich habe nicht einmal versucht, die anderen beiden zu installieren. Wenn ich davon ausgehe, wie würde ich die db in die Produktion migrieren? – mpen

4

Da Sie mod_wsgi im eingebetteten Modus verwenden, werden Ihre Änderungen nicht automatisch angezeigt. Sie sehen sie ab und zu, weil Apache manchmal neue Handler-Instanzen startet, die die Updates abfangen.

Sie können dies beheben, indem Sie den Daemon-Modus verwenden, wie beschrieben here. Insbesondere sollten Sie die folgenden Richtlinien, um Ihre Apache-Konfiguration hinzuzufügen:

WSGIDaemonProcess example.com processes=2 threads=15 display-name=%{GROUP} 
WSGIProcessGroup example.com 
+0

Ich brauche keine virtuellen Hosts, um diese Arbeit zu machen, oder? – mpen

+1

Ich nehme an, Sie können die Deklarationen einfach in den gleichen Kontext wie WSGIScriptAlias ​​setzen. –

+0

Das scheint überhaupt keine Wirkung zu haben, übrigens. – mpen

5

Lesen Sie die Dokumentation zu mod_wsgi, anstatt sich auf die minimalen Informationen für das Hosting von mod_wsgi auf der Django-Site zu verlassen. In partcular lesen:

http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode

Dies sagt Ihnen genau, wie Quellcode Arbeiten in mod_wsgi Nachladen, einschließlich eines Monitors Sie gleiche Art von Quellcode zu implementieren Nachladen, dass Django runserver tut verwenden können. Sehen Sie auch, welche Gespräche darüber geführt werden, wie man das auf Django anwendet.

http://blog.dscpl.com.au/2008/12/using-modwsgi-when-developing-django.html http://blog.dscpl.com.au/2009/02/source-code-reloading-with-modwsgi-on.html

16

den Prozess im Daemon-Modus ausgeführt wird nicht helfen. Hier ist, was passiert:

mod_wsgi erzeugt mehrere identische Prozesse, um eingehende Anfragen für Ihre Django-Website zu behandeln. Jeder dieser Prozesse ist ein eigener Python-Interpreter und kann eine eingehende Webanforderung verarbeiten. Diese Prozesse sind persistent (sie werden nicht für jede Anforderung hoch- und heruntergefahren), so dass ein einzelner Prozess tausende Anfragen nacheinander bearbeiten kann. mod_wsgi ist in der Lage, mehrere Webanfragen gleichzeitig zu bearbeiten, da es mehrere Prozesse gibt.

Der Python-Interpreter jedes Prozesses lädt Ihre Module (Ihre benutzerdefinierten Python-Dateien), wenn ein "Importmodul" ausgeführt wird. Im Kontext von Django tritt dies auf, wenn ein neues view.py aufgrund einer Webanfrage benötigt wird.Sobald das Modul geladen ist, befindet es sich im Speicher und Änderungen, die Sie an der Datei vornehmen, werden in diesem Prozess nicht berücksichtigt. Wenn mehr Webanforderungen eingehen, verwendet der Python-Interpreter des Prozesses einfach die Version des Moduls, die bereits im Speicher geladen ist. Sie sehen Inkonsistenzen zwischen den Aktualisierungen, da jede Webanforderung, die Sie erstellen, von verschiedenen Prozessen verarbeitet werden kann. Einige Prozesse haben möglicherweise Ihre Python-Module während früherer Versionen Ihres Codes geladen, andere haben sie möglicherweise später geladen (da diese Prozesse keine Webanforderung erhalten haben).

Die einfache Lösung: Wenn Sie Ihren Code ändern, starten Sie den Apache-Prozess neu. Meistens ist das so einfach wie das Ausführen als root von der Shell "/etc/init.d/apache2 restart". Ich glaube, dass auch ein einfaches Reload funktioniert, "/etc/init.d/apache2 reload"

Die Daemon-Lösung: Wenn Sie mod_wsgi im Daemon-Modus verwenden, müssen Sie nur noch berühren (Unix-Befehl) oder modifizieren Sie Ihre wsgi-Skriptdatei. Um den Beitrag von scrompt.com zu verdeutlichen, führen Änderungen an Ihrem Python-Quellcode nicht dazu, dass mod_wsgi Ihren Code neu lädt. Das Neuladen findet nur statt, wenn die wsgi-Skriptdatei geändert wurde.

Letzter Punkt zu beachten: Ich sprach nur über wsgi als Prozesse zur Vereinfachung zu verwenden. wsgi verwendet tatsächlich Thread-Pools in jedem Prozess. Ich habe nicht das Gefühl, dass dieses Detail für diese Antwort relevant ist, aber Sie können mehr darüber erfahren, indem Sie über mod_wsgi lesen.

+0

Schöne Erklärung! Vielen Dank. Ist dieses Thread-Pooling vorteilhafter/schneller als das, was PHP gerade tut? – mpen

+0

Bei der Verwendung von Multithreading müssen Sie mit der Python GIL konkurrieren. Daher können Sie für den rechenintensiven Request-Handler-Code etwas darunter leiden, dass Sie nicht mehrere CPUs/Kerne in einem Prozess nutzen können. Wenn Code auf Datenbanken und andere Module zugreift, die die GIL freigeben, ist das nicht so sehr ein Problem. Wie auch immer, viel komplizierter. Ich schlage vor, Sie lesen "http://blog.dscpl.com.au/2007/09/parallel-python-discussion-and-modwsgi.html". –

+0

BTW, Daemon-Modus kann helfen, wie Sie den Code-Monitor ausführen können, wie in mod_wsgi Dokumentation in anderen Antwort beschrieben beschrieben. Auf diese Weise kann jede Änderung an Python-Code, nicht nur an der WSGI-Skriptdatei, automatisch einen Neustart der Daemon-Prozessgruppe auslösen. –

Verwandte Themen