Edgar Ehritt: / (APACHE) Caching von Seiten - wann und wie?

Beitrag lesen

Re:

Ei, das wird ja doch eine zwiespältige Geschichte. Ich teile mal meine Antwort in die sich für mich herauskristallisierenden Themengebiete auf und antworte hier auf alle HTTP/Proxy-bezogenen Fragen:

Na ja, man könnte es ja auch so formulieren:"Um ein Caching zu realisieren, erstelle ich jeweils ein statisches Dokument meines Dynamischen, solange sich an diesem nichts ändert!".

Ja, so ist auch mein Ansinnen. Sicher ändert man immer wieder mal etwas an seinen Artikeln, und seien es eben nur die Rechtschreibfehler. (Bin da übrigens sehr leidgeprüft, meine eigenen Sachen nach längerer Zeit mir durchlesen zu müssen. ;) Inwieweit statische Dokumente für Dich sogar ein Platzproblem werden können, weiß ich natürlich nicht.

| Den zweiten, nicht unwesentlichen Punkt bei einem CMS sehe ich bei der Datenkompression. Komprimierte Dokumente werden sehr schnell und bandbreitenschonend durch die Leitungen gejagt. Der Standard heutiger Browsergenerationen besteht im Akzeptieren von komprimierten Inhalten. So senden alle entsprechende Accept-Encoding-Header. (Ja, es hat nichts mit Deinem eigentlichen Ansinnen zutun - ich hallte es dennoch für eine Überlegung wert.) Dies ist ein weiterer Vorteil von statischen Dokumenten, dass man nicht on-the-fly für Kompression zu sorgen hat.
... hat Content Negotiation nicht bei zwischengeschalteten Proxies das Problem, dass wenn nur eine Version gespeichert ist, der anfordernde Client u.U. entweder nicht die g-zippte Version bekommt, oder alle Clients nur die ungezippte Version?
Wie kann man das umgehen/ vermeiden?
Kann man erreichen, dass ein Proxy beide Versionen speichert und abhängig vom Header, den der jeweilige Client mitschickt, die passende Version ausliefert?

Das ist schon etwas komplexer aufgebaut; Beispielanfrage-antwort:

GET /projekt/artikel/ HTTP/1.1
Host: top-topics.com
Accept: */*;q=0.8, application/xml;q=0.9, application/xhtml+xml, text/html;q=1.0
Accept-Encoding: deflate;q=0.6, gzip;q=1.0
Accept-Language: en-us;q=0.2, en;q=0.4, de-at;q=0.6, de-de;q=0.8, de;q=1.0

HTTP/1.1 200 OK
Date: Sat, 27 Jun 2009 23:09:55 GMT
Vary: Negotiate,Accept,Accept-Language,Accept-Encoding
Content-Encoding: gzip
Content-Length: 442
Content-Type: text/html;charset=ISO-8859-1

Ein Proxy kann (naja, bin ich mal nicht ganz so idealistisch und sagen wir mal, _sollte_) nicht auf Gutdünken speichern was und wie er will. Hierbei ist der Header Vary entscheidend. Anhand des Request und des Vary-Headers werden Inhalte gespeichert. Nur eine Anfrage, die im obigen Beispiel die _selben_ Header Accept, Accept-Language und Accept-Encoding erneut an den Proxy sendet, darf dieser aus seinem Cache beantworten. D. h. ein Proxy kann (und sollte auch) zu einer Ressource mehre Entsprechungen parallel speichern. Findet ein Proxy zu einer Anfrage keine Entspechung, muss er die Anfrage weiterleiten. Wenn Du so willst, sind sie wie Kinder, die alles erstmal lernen müssen, bis sie auf Wiederholungen selbständig reagieren können - soweit die Theorie.

In der Praxis kann ein Proxy selbständig auch Änderungen an einer gespeicherten Ressource vornehmen. Sagen wir, er erhält eine (erneute) Anfrage zu einen gespeicherten Dokument mit Zeichenkodierung iso-8859-1. Diese Anfrage enthält aber im Header Accept-Charset eben diese Kodierung nicht. Dann kann er mittels Anbindung z. B. an die libiconv das Dokument zu einem akzepierten Zeichen transformieren. Selbes gilt auch für un-/komprimierte Ressourcen. Dies kann man aber durch "Cache-Control: no-transform" unterbinden.

Es kann immer zu Fehlern kommen. Jedoch, solange der Proxy von sich aus ohne Revalidierung serviert, muss Dich das eigentlich nicht kümmern. Dein Webserver ist nämlich daran völlig unbeteiligt und hat auch keine Möglichkeit festzustellen, ob dort jemand eines Deiner Dokumente gerade abfordert. Jedoch kannst Du grundsätzlich durch den Response-Header Cache-Control regeln, wie sich ein Proxy zu verhalten hat. Hierbei sei auf Werte must-revalidate und proxy-revalidate hingewiesen. (Auch ist es möglich dem Proxy die Möglichkeiten zu nehmen, indem man "Vary: *" sendet.)

Einziger Haken an der Sache, der mir jetzt auf Anhieb einfällt ist, dass wenn ich die (statischen) Dokumente mit einem Cache-Control oder Expires Header ausliefere, dann werden bspw. neue Kommentare auch erst nach Ablauf der angegebenen Zeitspanne für den jeweiligen Client "sichtbar". Und auch wieder das Problem mit den Proxies, oder?

Ja. Für solche Seiten, wo auch Kommentare verfasst werden, lohnt sich dann "Cache-Control: no-cache, no-store" zu setzen. Dabei verbleibt die letztendliche Validierung dann bei Browser (grob 14.24 bis 14.28) und Server (Etag, Last-Modified).

Allgemein sei hier auf Caching Negotiated Responses verwiesen, um auch den letzten Zweifel zu nehmen, was wie und warum zu funktionieren hat - äh - könnte, sollte, vielleicht doch müsste - naja. ;)

Gruß aus Berlin!
eddi

--
“Um etwas zu erschaffen mit gutem Erfolg, muß man aufhören das zu sein, was man ist; um ganz das zu werden, was man hervorbringen will.”