© filip robert/Shutterstock.com
Mit Varnish und dem Vary Header dynamische Inhalte effizient cachen

Varnish und der Vary Header


Das Cachen von Webseiten ist ein Thema, das leider oft zu spät mit in die Konzeption einbezogen wird. Wenn man sich schon im Vorhinein ein paar Gedanken zum Thema macht, kann man auch auf äußerst dynamischen Webseiten ungeahnte Performance erreichen.

Die Erinnerung an die Webseitenerstellung in den alten Zeiten kann ein angenehmes Gefühl auslösen: Man erstellte ein paar HTML-Dateien, dazu noch ein paar Bilder sowie ein Stylesheet, und schob das Ganze per FTP auf einen Server. Fertig war eine Webseite, die sogar noch ziemlich performant war! Doch so einfach das damals auch gewesen sein mag, würde man mit diesen schlussendlich doch sehr bescheidenen Möglichkeiten die Anforderungen heutiger moderner Projekte wohl nicht mehr erfüllen können.

Der Kunde möchte seine Webseite selbst verwalten können, deshalb setzt man heute üblicherweise Content Management Systeme (CMS) ein, die im Hintergrund noch mit einer Datenbank kommunizieren. Der ganze Stack ist jetzt schon um einiges komplizierter und auch langsamer geworden. Mittlerweile sind Webseiten oft schon sehr dynamisch. Es werden die letzten Artikel auf der Startseite dargestellt, der Name des eingeloggten Benutzers wird irgendwo angezeigt, oder man muss gar einen Newsfeed programmieren, der sowieso für jeden Benutzer anders aussieht. Und all das auf Kosten der Performance.

Werkzeuge wie Varnish [1] versprechen hier Abhilfe. Bei Varnish handelt sich um einen Cache für dynamische Webseiten mit viel Inhalt. Anstatt für jeden Request wieder die PHP-Applikation aufzurufen, zeitaufwendige Datenbankzugriffe auszuführen und das Ganze erst mit einer Templatesprache in HTML übersetzen zu lassen, versucht Varnish, sich die Antwort vom Request zu merken und liefert diese im Idealfall direkt aus dem Arbeitsspeicher aus. Das ist natürlich unvergleichbar viel schneller, weshalb es sich wirklich auszahlt, sich mit diesem Thema genauer auseinanderzusetzen.

Caching 101

Abhängig vom Betriebssystem kann man Varnish auf verschiedene Arten installieren und starten. Viele Linux-Distributionen bieten ein Package für Varnish an, wobei meist noch die Version 5.2 verwendet wird, auf die sich auch dieser Artikel bezieht. Nachdem man das Package erstellt hat, kann man Varnish entweder mit einem Service-Manager wie systemd starten oder man benutzt einfach das varnishd-Kommando auf der Kommandozeile.

Varnish setzt auf das HTTP-Protokoll. Das bedeutet, dass man es vor jede Applikation schalten kann, die über HTTP kommuniziert. Unter anderem spielt es keine Rolle, welche Programmiersprache oder welcher Webserver hinter Varnish läuft. Wir nutzen diesen Vorteil aus, indem wir einfach den PHP-internen Webserver nutzen. Der PHP-interne Webserver ist zwar nicht für den Einsatz in Produktionsumgebungen gemacht, allerdings kann er ohne viel weniger Konfigurationsaufwand benutzt werden.

Angenommen, der folgende Inhalt liegt als index.php im Verzeichnis, auf dem man sich gerade in der Kommandozeile befindet:

<?php sleep(1); echo 'War das anstrengend...';

Hier handelt es sich um ein sehr vereinfachtes Beispiel. Man kann aber annehmen, dass in einer realistischen Webanwendung, in der sehr viele Files eingelesen sowie Datenbankabfragen abgeschickt und Templates gerendert werden, durchaus einige Sekunden zum Erstellen der Antwort vergehen können. Dieses Beispiel kann man mit dem folgenden Kommando unter Benutzung des PHP-internen Webservers bereitstellen: php -S localhost:8000. Danach kann man in einem beliebigen Webbrowser localhost:8000 öffnen und sieht, wie sich der PHP-Prozess nach einer Sekunde beschwert, dass Schlafen ganz schön anstrengend sei. In diesem Beispiel fällt natürlich sofort auf, dass der schlussendliche Inhalt eigentlich immer der gleiche ist, unabhängig davon, wann diese Datei aufgerufen wird. Das heißt, hier würde sich Caching sehr anbieten. Wenn man sich für Varnish entscheidet, muss man eine Konfigurationsdatei bereitstellen, die in diesem Beispiel phpmagazin.vcl heißt (Listing 1).

Listing 1

vcl 4.0; backend default { .host = "localhost"; .port = "8000"; }

Mit dem Schlüsselwort backend teilt man Varnish mit, bei welchem Host und welchem Port sich die eigentliche Webapplikation befindet. Danach kann man Varnish mit folgendem Kommando auf der Kommandozeile starten: varnishd -a localhost:8080 -f /etc/varnish/phpmagazin.vcl -s malloc,64M -F

Achtung: Dieses Kommando muss bei manchen Systemen als root-Benutzer bzw. mit sudo ausgeführt werden.

Jetzt läuft Varnish auf Port 8080 und man bekommt die gleiche Antwort wie vorhin, wenn man localhost:8080 öffnet. Der Request dauert immer noch genauso lange wie vorher, allerdings beinhaltet die Response jetzt einen HTTP-Header namens Age, der angibt, wie viele Sekunden die Response schon im Cache liegt. Der Wert dieses Headers ist 0, wenn es sich um einen Cache Miss handelt, also Varnish bei der eigentlichen Webapplikationen nachfragen musste. Momentan verbessert sich die Antwortzeit auch nach erneutem Laden nicht. Der Age-Header behält seinen Wert, weil Varnish nicht weiß, ob die Seite gecacht werden darf. Es könnte sich um eine sehr dynamische Nachrichtenseite handeln, bei der jede Sekunde neue Inhalte ausgespielt werden. Um Varnish zu erklären, wie lange die Seite gecacht werden darf, setzen wir auf den HTTP-Request-Header namens Cache-Control. In Listing 2 wird Varnish die Response für zehn Sekunden aus seinem eigenen Cache liefern.

Listing 2

<?php header('Cache-Control: public, max-age=0, s-maxage=10'); sleep(1); echo 'War das anstrengend...';

Bevor die eigentliche Ausgabe getätigt wird, setzt die header-Methode von PHP einen HTTP-Header. Man muss dabei beachten, dass der Aufruf der header-Methode nur funktioniert, wenn davor ...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang