Inhalte als statische HTML Seiten cachen
StaticGenerator for Django ist eine einfache Anwendung die es erlaubt, (HTML)Seiten deines Django-Projekts statisch zu speichern und damit in Sachen Caching die maximale Performance zu erreichen.
Installation
Erstmal ein paar Notizen:
staticgenerator.py aka StaticGenerator for Django runterladen oder per easy_install staticgenerator installieren. Beachte: Vor Version 1.3 hieß das Modul nicht staticgenerator sondern nur generator.
Das Teil ins Projekt integrieren, siehe original Doku.
in der .htaccess Datei (siehe ApacheModWsgi) folgendes über der anderen RewriteRule hinzufügen:
RewriteCond %{HTTP_COOKIE} !sessionid=.*
RewriteCond /srv/http/80/www.example.com/htdocs%{REQUEST_URI}index.html -f
RewriteRule ^(.*)$ $1index.html [L]
(Eine alternative Vhost-Konfiguration findest du auf: StaticHtmlCacheAlternativeKonfiguration)
Damit werden alle Anfragen von Usern, die keinen Session Cookie haben (anonyme User, Suchmaschinen, etc) vom Apache mit der statischen Version der Seite, sofern sie existiert, bedient.
Beachte aber, dass selbst wenn du dich aus dem Django-Admin ausloggst, dein Session-Cookie in deinem Browser nicht gelöscht wird.
GZipping von den statischen Seiten
Beachte, dass bei statischen Seiten die GZipMiddleware von Django nicht mehr wirkt. Um die statischen Seiten auch gzip'd zu publishen, baue einfach ApacheModDeflate mit in deiner Vhost-Konfiguration ein.
Statische Seiten nach einer bestimmen Zeit löschen
Der StaticGenerator liefert eine Funktion quick_delete(url) mit, mit der sich die Seiten wahlweise löschen lassen. Alternativ kannst du die Dateien direkt auf deinem System löschen, dieser Befehl löscht alle Dateien, die vor mehr als 20 Minuten erzeugt wurden:
find /srv/vhosts/mahner.org/www/cache_static/ -type f -mmin +20 -delete
Idealerweise rufst du diesen Befehl in einem Crontab alle 5 Minuten auf.
Seiten beim Speichern oder Löschen von Kommentaren neu erzeugen
Folgender Code erzeugt eine statische Seite beim Speichern eines Article Objekts. Außerdem wird beim Speichern oder Löschen eines Kommentars die Seite neue erzeugt. Und als Bonus werden noch Flatpages statisch generiert, wenn sie gespeichert werden.
from django.contrib.comments.models import FreeComment
from django.contrib.flatpages.models import FlatPage
from django.dispatch import dispatcher
from django.db.models import signals
from myproject.utils.generator import quick_publish, quick_delete
from myproject.myapp.models import Article
def publish(sender, instance):
quick_publish(instance)
def republish(sender, instance):
try:
quick_delete(instance.get_content_object())
except:
pass
quick_publish(instance.get_content_object())
dispatcher.connect(publish, sender=Article, signal=signals.post_save)
dispatcher.connect(publish, sender=FlatPage, signal=signals.post_save)
dispatcher.connect(republish, sender=FreeComment, signal=signals.post_save)
dispatcher.connect(republish, sender=FreeComment, signal=signals.post_delete)
Benchmark
Ein kurzer Vergleich mit ab (Apache Bench) zeigte folgenden Unterschied:
Eingeloggter User:
HTML transferred: 8232106 bytes Requests per second: 82.04 [#/sec] (mean)
Anonymer User:
HTML transferred: 8238320 bytes Requests per second: 764.04 [#/sec] (mean)
Die leicht unterschiedliche Datenmenge liegt daran, dass eingeloggte User mit Namen begrüsst werden.



