max-age = 0, aber warum?
Anfang dieser Woche haben wir smoke vorgestellt. Ein wirklich einfach zu verwendendes Lean Testing Tool. Das kleine Helferlein findet zum Beispiel „falsche“ Header. Oder besser, es findet Header, die ungewöhnlich sind. Ob sie falsch sind, muss dann jeder selbst entscheiden. So gehen wir zum Beispiel davon aus, dass ein max-age: 0 in den meisten Fällen eine Ausnahme ist. Bei einer Login-Seite oder ähnlichem könnte man dies akzeptieren.
Das war jetzt erstmal so die übliche Herangehensweise für Header. Man kann es aber auch ganz anders aufziehen. Wir haben bei unserem Projekt www.amilio.de zum Beispiel bei jeder HTML ein max-age:0. Aber warum? Die Antwort ist Cache-Invalidierung. Klingt jetzt erstmal verwirrend, deswegen etwas mehr Info zu unserem Set-Up.
Wir haben eine ganz normale Symfony2-Applikation am laufen. Was die meisten kleinen Seiten jetzt nicht haben, ist ein Webcache vor dem Angebot. Wir aber schon. In diesem Fall ein Varnish. Den Webcache kann mit mit einem geteilten Browser-Cache vergleichen. Er nimmt die Anfragen entgegen und wenn er etwas im Speicher hat, was noch gültig ist, gibt er es aus, ohne die eigentliche PHP-Applikation zu bemühen. Soweit so gut.
Wir wollten mit amilio eine sehr performante Webanwendung bauen und haben massiv auf Caching und Invalidierung gesetzt. Im ersten Schritt haben wir einfach die Cache-Header auf 5 Minuten gesetzt, wenn wir eine Produktliste ausgeliefert haben. Das geht aber leider nur so lange gut, wie man keine neuen Produkte in seine Liste aufnimmt. Wäre doch schön, wenn die gleich erscheinen.
Nächster Schritt war es also den Cache zu invalidieren. Dazu haben wir ein wunderbares Bundle gefunden (friendsofsymfony/http-cache-bundle), welches uns hilft den Varnish zu purgen. Wenn jetzt ein User ein neues Produkt hinzufügt löschen wir die Produktliste aus dem Varnish und die nächste Anfrage baut die Seite wieder so auf wie es sein soll. Fertig? Nein, leider nicht.
Wir haben jetzt zwar die Seite auf dem Webcache geworfen, im Browsercache ist sie aber immer noch drinnen. Dummerweise kommen wir da aber nicht dran. Das heißt, solange der Nutzer keinen Shift-Reload macht, wird er vom Browser bedient und die Seite wird veraltet ausgeliefert.
Hier kommt jetzt das max-age:0 zum tragen. Wir haben den Varnish so konfiguriert, dass er bei jeder URL eines bestimmten Musters, die Cache-Header so manipuliert, dass ein max-age:0 ausgespielt wird (pragma: no-cache würde es auch tun). Auf diese Weise wird der Browser niemals HTML-Seiten unserer Domain vorhalten und immer wieder die neue Seite abholen. Der Varnish hingegen übernimmt die echten Cache-Zeiten.
Obwohl wir sagen, dass wir so lange und so gut cachen wollen, wie es geht, nehmen wir in Kauf, dass ein Nutzer, der zweimal auf die gleiche URL geht, diese auch doppelt abruft. Aber wie oft geschieht dies schon.
Wer seinen Varnish identisch konfigurieren will, hier der vcl-Code:
sub vcl_deliver {
if (!(req.url ~ "^/images/") && !(req.url ~ "^/upload/")) {
set resp.http.cache-control = "max-age=0";
}
}
1 Comments