Edge Side Includes
Da ich gerade dabei bin mit Mike zusammen einen Artikel für die ix zu schreiben und das Thema ESI (Edge Side Includes) angerissen wird, habe ich mir gedacht, ich schreibe hier auch mal eine ganz kurze Übersicht über das meiner Meinung nach wichtigste Feature dieser Technologie.
Betrachtet man das Caching-Verhalten einer Webseite, dann bemerkt man, dass sie so lange gültig sein kann, wie das aktuellste Element auf ihr. Existiert zum Beispiel eine Box mit den aktuellsten Nachrichten, die jede Minute aktualisiert werden muss, so kann man mit reinem HTML da nichts machen. außer die komplette Seite maximal für eine Minute im Cache des Nutzers zu legen. Eigentlich eine nicht wirklich optimale Vorgehensweise, da die meisten Systeme zusätzlich so aufgebaut sind, dass sie immer die ganze Seite berechnen wenn eine Anfrage kommt. Gut einiges liegt im Cache, aber vieles eben auch nicht.
ESI kann dazu genutzt werden, dieses Problem ein wenig abzuschwächen und vielleicht sogar zu lösen. Eigentlich von Akamai vor einigen Jahren erfunden, wurde es 2001 als offizieller Standard bei der w3c eingereicht. Man braucht also keine Angst haben, dass man sich bei Verwendung auf eine Technologie festlegt, die keine Zukunft hat. Fangen wir aber an das Feature zu beleuchten, dass uns bei unserem Problem helfen kann.
Edge Side Includes bieten einem die Möglichkeit die Webseite in einzelne Bestandteile aufzuteilen und diese somit auch wie eigene HTML-Seiten zu betrachten. Nehmen wir an, der Header unserer Seite würde als ein solcher Bestandteil gekennzeichnet werden. Wir haben nun die Möglichkeit genau diesen Header einzeln zu Cachen und das schöne ist, wir nutzen die HTTP-Header, die wir eh schon kennen. Im ESI-Jargon sprechen wir einfach mal von includes und es würde wie folgt aussehen:
<esi:include src="http://phphatesme.com/header.php" />
Ziemlich einfach und verständlich, oder? ESI wird, wie man sieht, über XML-Elemente direkt im HTML gesteuert. Natürlich immer im ESI-Namespace, so wie es sich gehört. Jetzt kann man sich natürlich fragen, wer ein solches Tag versteht, die header.php anruft und die eigentliche Seite zusammenbaut. Varnish oder Squid wären hier zum Beispiel zwei Kandidaten.
Um diese Tags zu verarbeiten schaltet man eine Instanz vor den Webserver, der diese interpretieren kann. Einige HTTP-Acceleratoren können dies. Wir haben gute Erfahrungen mit Varnish gemacht. Egal welches Tool, es werden die einzelnen Bestandteile zusammengefügt und nach allen HTTP-Gesichtspunkten verarbeitet. Caching funktioniert also weiterhin wie gehabt. Nachdem alle Schnippsel abgeholt wurden, wird eine ganze Seite zusammengesetzt, die ESI-Tags rausgeworfen und ausgeliefert. Einfach, oder? Also zumindest das Prinzip und wenn man ein wenig mit einem HTTP-Accelerator rumgespielt hat, sollte einem hier kaum etwas spanisch vorkommen.
Da alle Tags entfernt werden ist diese Technologie für den Endkunden, also die Person, die am Browser sitzt komplett transparent. Es hat keine Ahnung rauszufinden, was da im Hintergrund passiert und trotzdem gewinnt man in den meisten Fällen sehr viel Performance auf den Servern, denn nicht mehr die ganze Seite, sondern nur einzelne Teile müssen berechnet werden.
Suchmaschinen bekommen übrigens auch ein vollständiges HTML-File, was ein großer Vorteil gegenüber AJAX ist, mit welchem man dieses System ja auch ohne Probleme hätte umsetzen können.
Falls Interesse besteht, würde ich noch Folgeartikel schreiben, denn etwas über Symfony2 und ESI hätte ich noch parat, wann ESI keinen Vorteil bringt, was ESI noch kann und wo Fallstricke lauern. Wären also vier an der Zahl, die ich wohl aufs restliche Jahr verteilen werde.
ESI-Includes sind zwar toll, allerdings muss man sie trotzdem mit Vorsicht genießen, da jeder ESI-Include einen weiteren Request an einen Webserver bedeutet und die Website frühestens nach dem Abarbeiten aller ESI-Includes an den Browser ausgegeben werden kann.
Was ich nie verstanden habe: Ich habe entweder (a) eine voll-dynamisch zu beantwortende Anfrage (private Sicht) mit einigen statischen, cachebaren Inhalten ODER (b) eine hauptsaechlich statische Seite mit einem kleinen dynamischen Teil. Beispiele wären: (a) eine „Mein profil“ Seite mit einem Header/Footer und (b) eine 5 minütlich aktualisierte News-Seite mit einer kleinen persönlichen Begrüßung für eingeloggte User.
So oder so, ein dynamischer Request lässt der Surrogate Server durch und mein PHP-Hochzeitstorten-Framework bekommt einen Hit. Wenn mein PHP erstmal angelaufen ist und mein FW erstmal gebootstrapped ist, dann kann ich die statischen Inhalte auch schnell ankleben und die shared-expiry selber berechnen.
Da spart mit der Reverse Proxy doch nicht viel Last, wenn er das macht, oder? Gut man kann die dann natürlich weltweit verteilen – und man programmiert seine Seiten viel modularer … Naja, und der Proxy dämpft die Cache-Stampedes ab und hat alles in allem ja etwas kleiner Füße als PHP.
Hab ich da etwas falsch verstanden? Oder geht es hauptsächlich um eher statische Inhalte.
Das scheint ein echt spannendes Thema zu sein, also gerne mehr Artikel dazu 🙂
(Natürlich besonders gern zu Symfony2 und ESI…)
@Marc: Ja auf den ersten Blick ja… aber da ja jede einzelne gecachte Komponente dafür in diversen Anfragen benutzt werden kann (N-Client für N verschiedenene Seiten) und der Reverse Proxy sich auch um die multiplen Hits kümmert (stale-while-revalidate) – ist das insgesamt gesehen besser.
Außerdem gilt das ja nur bei ganz leerem Cache – danach sollten die einzlenen „Laufzeiten“ der Komponenten nicht exakt synchron sein.
Dazu müssten die Komponenten ja erst mal gecacht werden. Wir arbeiten hier mit Magento und haben z. B. die Detailseiten bis auf ein paar ESI-Includes komplett gecacht. Die Inhalte der Includes können nicht gecacht werden. Wir haben die Erfahrung gemacht, dass sich bei einigen Inhalten, die eben doch etwas länger dauern, der Ajax-Weg der bessere ist, um dem Benutzer die Seite eben schneller presäntieren zu können.
Nichtsdestotrotz sind ESI-Includes eine tolle Sache.
Hau alles raus was du zu ESI parat hast.
Ist ein spannendes Thema. Vor allem wann ESI nichts bringt finde ich selbst sehr interessant zu wissen.
Esi ist auf jedenfalls eine interessante Sache. Habe es zwar noch nicht produktiv im Einsatz, da ich gerade erst erste Versuche mit Varnish mache, werde da dann wohl aber um esi nicht herumkommen wenn ich eine vernünftige TTL erreichen möchte.
Ich denke der Vorteil an esi ist, dass diese Blöcke auch wieder gecached werden können, und der Besucher so in der Regel eine Seite bekommt, die trotzdem rein vom Cache ausgeliefert werden kann, was nahe an die Performance einer gecachten Seite ohne esi rankommen dürfte.
Einen Artikel über ESI und Symfony2 würde mich sehr interessieren