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

Hallo Selfgemeinde!

Im Zusammenhang mit der Überlegung für den Aufbau eines kleinen "Mini-CMS" für meine kleine private Homapage (lose Artikelsammlung), stehe ich (persönlich erstmals) vor der Frage, wie man ggf. einen "Caching-Mechanismus" am besten/ sinnvollsten realisiert, bzw. ob sich der Aufwand für kleine Sites überhaupt lohnt?

Mal angenommen, er lohnte sich:
Welche "Methode" ist dann empfehlenswert/ die effizienteste?
Und auf welche (grundsätzliche) Methode sollte man zurückgreifen? Also bspw. lieber einen PHP Caching Skript verwenden, oder doch eher auf eines/ mehrere der Apache mod_cache Module zurückgreifen? Oder beides kombiniert?

Worauf ist grundsätzlich bei einem effektiven Caching zu achten?
Welche Dinge kann/ sollte man grundsätzlich besser nie cachen?
Und wie schließt man diese dann davon aus?

Auf welche besonderen Dinge muss man achten, wenn man z.B. Sessions verwendet und/ oder Seiten hat, die eine Authentifizierung erfordern?

Ihr seht, Fragen über Fragen ...!
Gerne lese ich mich auch selber weiter in das Thema ein. Hierzu würde ich mich über entsprechende Links zu brauchbarer Literatur im Netz freuen.

Natürlich wäre ich genauso erfreut über jegliche Erklärung zu dem Thema. :-)

Wie immer vorab schon mal meinen besten Dank für eure freundliche Hilfe!

Gruß Gunther

PS: Falls es für die Überlegung(en) hilfreich ist - die Artikel sollen in einer (MySQL) DB gespeichert werden. Ob für einen rein lesenden Zugriff überhaupt eine Session angelegt werden soll, weiß ich noch nicht. Vermutlich aber schon. Ein Login dürfte höchstwahrscheinlich u.a. für die Kommentarfunktion von Nöten sein. Je nach Seite dürfte es aller Wahrscheinlichkeit nach angepasste (dynamische) (Unter-)Menüs geben.

  1. Hallo Guther,

    es lohnt meines Erachtens sich darüber Gedanken zu machen, auch wenn man nicht für das Serverhosting Verantwortung trägt, Ressourcen möglichst sparsam einzusetzen. Auch wenn dies nicht wirklich notwendig ist, so hat es doch einen ungemein lehrreichen Charakter. ;)
     Generell würde ich die Frage nach dem caching mal hinten anstellen und viel grundsätzlicher herangehen. Dann stellt sich die Frage: Statisch oder dynamisch.

    Statische Dokumente werden gegenüber dynamischen sehr ressourcenschonend serviert. Sie bringen durch die Möglichkeiten der allermeisten Webserver (in in Deinem Fall, dem Apachen, sowieso) "nativ" erhebliche Vorteile mitsich. An dieser Stelle verweise ich mal auf den entsprechenden Teil des Artikels von Christian Kruse, um kurz die Vorteile darzustellen.

    Generell geht es Dir ja um caching. Wie zu sehen ist, bringen statische Dokumente dieses per HTTP-Header Etag und Last-Modified mit, zum Preis eben _statische_ Inhalte zu haben. Dieser Mechnaismus müsste bei dynamischen Dokumenten erst erstellt werden (was aber auch möglich ist, nur warum sollte man? ;). Kurz umrissen, müssten dann alle eingebundenen Dateien (bei Dir ja eher Datenbanksätze) und Daten ($_REQUEST, $_SERVER) für das Generieren eines Etag-Headers zu einem Hash herangezogen werden. Damit hätte man zwar dynamische Inhalte, jedoch sollte man immer(!) davon ausgehen, dass zwischen Endnutzer mit seinem Browser und dem Webserver auch Proxies zwischengeschaltet sind (AOL). Somit hat man eben auch für einen korrekten Vary-Header zu sorgen. Alles in allem ist dies möglich (persönlich aber wäre es mir bei einer Artikelsammlung zu viel Aufwand).
     So favorisiere ich den Etag i. V. m. statischen Dokumenten, da er eine Integritätsprüfung darstellt und somit, die von Dir angesprochene Frage, was man gar nicht cachen sollte, sich erübrigt.

    Das heißt also, ich würde vor jedem noch so ausgeklügeltem Cache-Mechanismus statischen Dokumenten den Vorrang geben. Der Grund liegt auf der Hand: Ums cachen kümmert sich allermeist nämlich der Browser selbst. Also kann ich mich den Inhalten widmen. ;)

    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.
     Allermeist kommt PHP auch mit der Erweiterung für die Zlib daher. Durch PHP erstellte statische Dokumente sollten also zum einen unkomprimiert auf dem Webspace gelagert werden, wie auch in ihrer komprimierten Entsprechung. Für das korrekte ausliefern muss man wiederum keine eigenen Codes erstellen, sondern es reichen auch hier wieder die bordeigenen Mittel der meisten Webserver für Content Negotiation aus.

    Die Herangehensweise ist also recht simpel umrissen: Erstelle Dir Templates fürs Layout in dem der jeweilige Inhalt durch PHP eingesetzt wird. Jedoch sollen die so erzeugten Dokumente nicht jedes mal neu erstellt, sondern auf dem Webspace statisch hinterlegt werden. Bei jedem Ändern eines Artikels, müssen nur die entsprechenden Dokumente überschrieben werden. Soweit dies auch sich häufig ändernde Menüeinträge betrifft, heißt dies zwar ein relativ häufiges Überschreiben der Dokumente, jedoch gleicht sich dies eben durch die oben schon erwähnten HTTP-Mechanismen sehr komfortabel aus.

    Das ist nun eine komplett anderes Konzept, was Du aus Deinen Fragen ersichtlich, sicher gehen wolltest. Meiner Ansicht nach lohnt es dennoch mal darüber nachzudenken, ob man für ein paar Artikeln, wenn man sich schon Gedanken um caching macht, nicht besser statische Dokumente erstellt.

    Session: Selbst sehe ich die heutigen Zustände, wo ich alle Kekse selbst abnicke/ablehne, mit Argwohn, dass für den Nutzer überwiegend Grundlos auf 80% aller Sites Session genutzt werden. Da bitte ich wirklich in Dich zu gehen, ob bei einem reinem Lesezugriff, Sessions sein müssen.

    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.”
    1. Lass mich noch einen weiteren Gedanken, der mir verspätet kam, nachsetzen:

      Bei jedem Ändern eines Artikels, müssen nur die entsprechenden Dokumente überschrieben werden. Soweit dies auch sich häufig ändernde Menüeinträge betrifft, heißt dies zwar ein relativ häufiges Überschreiben der Dokumente, jedoch gleicht sich dies eben durch die oben schon erwähnten HTTP-Mechanismen sehr komfortabel aus.

      Ich möchte an dieser Stelle auch einwerfen, den hier über all die Jahre sehr hartnäckig in die Köpfe eingeprügelten Lehrsatz -auf Frames zu verzichten- völlig vorurteilsfrei zu überdenken! Denn Frames für eine, sich auf absehbare Zeit stetig wandelnde Menüstruktur, haben erhebliche Vorteile. So wird nur der "Teil des Dokuments" (also der Frame), der sich tatsächlich ändert, erneut ausgeliefert.

      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.”
      Wohl dem, der sich dann noch im Spiegel ansehen kann.
      1. Hi,

        Ich möchte an dieser Stelle auch einwerfen, den hier über all die Jahre sehr hartnäckig in die Köpfe eingeprügelten Lehrsatz -auf Frames zu verzichten- völlig vorurteilsfrei zu überdenken! Denn Frames für eine, sich auf absehbare Zeit stetig wandelnde Menüstruktur, haben erhebliche Vorteile. So wird nur der "Teil des Dokuments" (also der Frame), der sich tatsächlich ändert, erneut ausgeliefert.

        Auch vorurteilsfrei betrachtet wiegt dieser eine (vermeintliche) Vorteil die zahlreichen Nachteile nicht auf.

        MfG ChrisB

        --
        Light travels faster than sound - that's why most people appear bright until you hear them speak.
    2. Hallo Eddi,

      vielen Dank für deine sehr hilfreiche & ausführliche Erläuterung!

      es lohnt meines Erachtens sich darüber Gedanken zu machen, auch wenn man nicht für das Serverhosting Verantwortung trägt, Ressourcen möglichst sparsam einzusetzen.

      ACK. Dies sollte imho auch immer einer der Grundsätze bei der Entwicklung/ Planung und Umsetzung sein.

      Auch wenn dies nicht wirklich notwendig ist, so hat es doch einen ungemein lehrreichen Charakter. ;)
      Generell würde ich die Frage nach dem caching mal hinten anstellen und viel grundsätzlicher herangehen. Dann stellt sich die Frage: Statisch oder dynamisch.

      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!".

      Das heißt also, ich würde vor jedem noch so ausgeklügeltem Cache-Mechanismus statischen Dokumenten den Vorrang geben. Der Grund liegt auf der Hand: Ums cachen kümmert sich allermeist nämlich der Browser selbst. Also kann ich mich den Inhalten widmen. ;)

      Dem stimme ich grundsätzlich auch zu: Dinge, die es schon gibt, muss ich nicht nochmal nachbauen! Oder anders formuliert: Ich will das Rad nicht neu erfinden. ;-)

      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.
      Allermeist kommt PHP auch mit der Erweiterung für die Zlib daher. Durch PHP erstellte statische Dokumente sollten also zum einen unkomprimiert auf dem Webspace gelagert werden, wie auch in ihrer komprimierten Entsprechung. Für das korrekte ausliefern muss man wiederum keine eigenen Codes erstellen, sondern es reichen auch hier wieder die bordeigenen Mittel der meisten Webserver für Content Negotiation aus.

      Das ist sicherlich auch eine effektive Maßnahme, die ich eigentlich auch immer verwende. Aber 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?

      Die Herangehensweise ist also recht simpel umrissen: Erstelle Dir Templates fürs Layout in dem der jeweilige Inhalt durch PHP eingesetzt wird. Jedoch sollen die so erzeugten Dokumente nicht jedes mal neu erstellt, sondern auf dem Webspace statisch hinterlegt werden. Bei jedem Ändern eines Artikels, müssen nur die entsprechenden Dokumente überschrieben werden. Soweit dies auch sich häufig ändernde Menüeinträge betrifft, heißt dies zwar ein relativ häufiges Überschreiben der Dokumente, jedoch gleicht sich dies eben durch die oben schon erwähnten HTTP-Mechanismen sehr komfortabel aus.

      Ja, diese Methode scheint mir doch der ideale Kompromiss aus Aufwand und Nutzen zu sein. Wie oben schon erwähnt, könnte man (würde ich) das auch noch mit unter den Begriff "Caching" fassen.
      BTW: Wie stelle ich es denn am einfachsten/besten/elegantesten an

      • automatisch nach jeder Änderung (neuer Artikel, neuer Tag, neue Kategorie, bei Updates der vorgenannten Punkte) eine neue statische Version der betroffenen Dokumente zu erstellen?
      • jeweils eine g-zippte Version davon auf dem Server zu speichern?

      Das ist nun eine komplett anderes Konzept, was Du aus Deinen Fragen ersichtlich, sicher gehen wolltest.

      Nein, so weit ist es gar nicht davon entfernt. Da es ja mit Sicherheit eine recht kleine Seite mit wenigen Besuchern wird, sollte sich der Aufwand dementsprechend in Grenzen halten. Trotzdem möchte ich es vom Grundprinzip her aber halt schon "ordentlich/ vernünftig" machen.

      Meiner Ansicht nach lohnt es dennoch mal darüber nachzudenken, ob man für ein paar Artikeln, wenn man sich schon Gedanken um caching macht, nicht besser statische Dokumente erstellt.

      Ja, grundsätzlich überzeugen mich die Vorteile dieser Methode(n) schon. 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?

      Session: Selbst sehe ich die heutigen Zustände, wo ich alle Kekse selbst abnicke/ablehne, mit Argwohn, dass für den Nutzer überwiegend Grundlos auf 80% aller Sites Session genutzt werden. Da bitte ich wirklich in Dich zu gehen, ob bei einem reinem Lesezugriff, Sessions sein müssen.

      Na ja - einen der Hauptvorteile davon sehe ich halt darin, dass ich einen User "identifizieren" kann, was zwingende Voraussetzung für diverse andere Dinge ist. So könnte man bspw. auf noch ungelesene Artikel hinweisen oder einfach auch nur den "Komfort" für den User erhöhen. Denn eigentlich halte ich diese Sache noch für relativ "nebenwirkungsfrei" für den User.

      Und wer das halt nicht möchte, kann ja auch durch eigene Entscheidung darauf verzichten (indem er bspw. den Cookie ablehnt, da ich bewußt auf trans_sid verzichte).

      Gruß Gunther

      1. Re:

        Hier nehme ich mal zur Frage der Umsetzung Stellung:

        Wie stelle ich es denn am einfachsten/besten/elegantesten an

        • automatisch nach jeder Änderung (neuer Artikel, neuer Tag, neue Kategorie, bei Updates der vorgenannten Punkte) eine neue statische Version der betroffenen Dokumente zu erstellen?
        • jeweils eine g-zippte Version davon auf dem Server zu speichern?

        Im einfachsten Fall sitzt Du vor einem HTML-Formular in Deinem Administrationsbereich, das den Inhalt aufnimmt. Das verarbeitende Script kann dann Wahlweise, den übergebenen Inhalt (Text[e], Bilder, Files) in eine Datenbank speichern. Bei einer Änderung holt es die entsprechenden Inhalte aus der DB oder parst wahlweise das HTML-Dokument und bringt die entsprechenden Texte (etc.) im Administrationsformular zur Überarbeitung zur Anzeige. Parallel dazu wird beim Verarbeiten mittels Dokumentenschablone der Formularinhalt zu einem Dokument geformt, abgespeichert und komprimiert.
         In dem Sinne kann der Administrationsbereich auch auf einem Heimrechner sein. PHP nimmt dann beispielsweise via FTP Änderungen vor.

        Beim erstellen eines gänzlich neuen Artikels, ist es dann eine Frage der Verarbeitungslogik, ebenso Anpassungen im Menü-Template vorzunehmen, was in die Dokumente einfließt.

        Na ja - einen der Hauptvorteile davon sehe ich halt darin, dass ich einen User "identifizieren" kann, was zwingende Voraussetzung für diverse andere Dinge ist. So könnte man bspw. auf noch ungelesene Artikel hinweisen oder einfach auch nur den "Komfort" für den User erhöhen. Denn eigentlich halte ich diese Sache noch für relativ "nebenwirkungsfrei" für den User.

        Diesen Komfort bieten statische Dokumente so ganz ohne Weiteres natürlich nicht. Genau da sehe ich aber das eigentliche Haar in der "statischen Suppe". Relevant sind solche Annehmlichkeiten natürlich nicht für eine Suchmaschine, so könnte man dies dann wiederum in einem Iframe unterbringen.

        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.”
      2. 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.”
        1. Hi!

          Ich übe & lese fleißig, um die ganzen Sachen auch mal langsam zu verstehen.
          Jetzt war ich schon fast der Meinung, ich hätte einen Teil davon bereits verstanden, aber mein Server + Browser sagen mir etwas anderes.

          Ich kriege sie nicht dazu, dass bei einer erneuten Anforderung ein 304 gesendet wird.
          Stattdessen erhalte ich immer folgenden Antwortheader (nachfolgend beide aufgeführt):

          GET /index.html HTTP/1.1
          Host: xxx.xx
          User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.1) Gecko/20090624 Firefox/3.5 (.NET CLR 3.5.30729)
          Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
          Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
          Accept-Encoding: gzip,deflate
          Accept-Charset: UTF-8,*
          Keep-Alive: 300
          Connection: keep-alive
          If-Modified-Since: Sun, 14 Jun 2009 10:54:04 GMT
          If-None-Match: "21a381-3b-46c4cc28a4b00"-gzip
          Cache-Control: max-age=0

          HTTP/1.x 200 OK
          Date: Sun, 28 Jun 2009 15:05:08 GMT
          Server: Apache
          Last-Modified: Sun, 14 Jun 2009 10:54:04 GMT
          Etag: "21a381-3b-46c4cc28a4b00"-gzip
          Accept-Ranges: bytes
          Vary: Accept-Encoding
          Content-Encoding: gzip
          Cache-Control: public, max-age=60
          Content-Length: 71
          Keep-Alive: timeout=15, max=100
          Connection: Keep-Alive
          Content-Type: text/html; charset=UTF-8

          Sieht evt. jemand "auf den ersten (oder auch zweiten) Blick" woran das liegt/ liegen könnte?

          Gruß Gunther

          1. Re:

            GET /index.html HTTP/1.1

            If-None-Match: "21a381-3b-46c4cc28a4b00"-gzip

            HTTP/1.x 200 OK

            Etag: "21a381-3b-46c4cc28a4b00"-gzip

            Sieht evt. jemand "auf den ersten (oder auch zweiten) Blick" woran das liegt/ liegen könnte?

            Derzeit gibt es einen Apache Bug in der 2.2.*-Version. Es liegt also nicht daran, dass der Mechanismus nicht funktioniert, oder Du etwas dafür kannst.
             Sieh Dir den work around an, der behebt das Problem. ;)

            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.”
            1. Hi Eddi!

              Derzeit gibt es einen Apache Bug in der 2.2.*-Version. Es liegt also nicht daran, dass der Mechanismus nicht funktioniert, oder Du etwas dafür kannst.
              Sieh Dir den work around an, der behebt das Problem. ;)

              Besten Dank für den Hinweis!
              Da fängt man ja schon (wieder) an, seinem Verstand zu misstrauen ...! ;-)

              Gruß Gunther

  2. hi,

    Im Zusammenhang mit der Überlegung für den Aufbau eines kleinen "Mini-CMS" für meine kleine private Homapage (lose Artikelsammlung), stehe ich (persönlich erstmals) vor der Frage, wie man ggf. einen "Caching-Mechanismus" am besten/ sinnvollsten realisiert, bzw. ob sich der Aufwand für kleine Sites überhaupt lohnt?

    Da kann ich dir Smarty empfehlen, dass bringt den Caching-Mechanismus von Haus aus mit (und ein Effektives dazu).
    Smarty legt eine kopie von den erzeugten Ressourcen in ein Cache-Verzeichnis und liefert die Seiten nach dem Cachen aus diesem Verzeichnis, sprich die Inhalte werden nur einmal geparst und gespeichert.
    Zu dem kommt, dass Smarty auch bei bereits besuchten Seiten die richtigen Header, in dem Fall 304 Not Modified mitsendet, so dass diese Seiten aus dem Browsercache geladen werden können.

    Welche Dinge kann/ sollte man grundsätzlich besser nie cachen?

    Dynamische Seiten, Bspw. Seiten mit einer Kommentarfunktion oder Gästebücher.
    Wobei man hier unterscheiden muss; wenn der User nur lesend unterwegs ist, kann er die Inhalte aus dem Cache haben, wenn er einen Beitrag schreiben möchte, muss dass Caching deaktiviert werden.

    Und wie schließt man diese dann davon aus?

    Mit Smarty:

    /*  
     * Wenn User was schreiben möchte oder eingelogged, nicht cachen  
    */  
      if (isset($_GET['write']) OR isset($_logged))  
      {  
        $smarty->caching = false;  
      }  
      else  
      {  
        $smarty->caching = true;  
        $smarty->cache_lifetime = 18000;  // bei mir auf 5 Stunden  
        $smarty->compile_check = false;  
        $smarty->force_compile = false;  
        $smarty->cache_modified_check = 1;  
      }  
      
      $smarty->display('my.tpl', $_SERVER['REQUEST_URI']);
    

    Wenn ein neuer Beitrag geschrieben wurde, muss dass Cache-Verzeichnis gelöscht werden, ansonsten wird der Beitrag erst in der Seite erscheinen, wenn cache_lifetime abgelaufen ist.

    Auf welche besonderen Dinge muss man achten, wenn man z.B. Sessions verwendet und/ oder Seiten hat, die eine Authentifizierung erfordern?

    Dann wird das Caching nichts bringen; Cache bedeutet, dass der User eine Kopie der Inhalte bekommt, ob vom Server oder aus dem Browsercache, ist in diesem Fall egal.

    Ob für einen rein lesenden Zugriff überhaupt eine Session angelegt werden soll, weiß ich noch nicht. Vermutlich aber schon.

    Für nur lesenden Zugriff würde ich das Caching bevorzugen, einmal deinem Traffic, zum anderen deinen Usern zuliebe, da Ressourcen nicht immer wieder geladen werden müssen und die Seiten zum Teil schneller ausgeliefert werden.

    Ein Login dürfte höchstwahrscheinlich u.a. für die Kommentarfunktion von Nöten sein. Je nach Seite dürfte es aller Wahrscheinlichkeit nach angepasste (dynamische) (Unter-)Menüs geben.

    Wie gesagt, Login und Generell Seiten, die durch die User in irgendeiner Form verändert werden können, wird das Caching nicht funktionieren.

    Wobei Smarty auch für diesen Fall einige Funktionen mitbringt, wie Bspw. Blockweise Cachen, und teile der Seite Dynamisch halten (nur wird das dann mit den Session wieder schwierig).

    mfg

    --
    --
    1. Hi,

      auch dir erstmal schon vielen Dank für deine Ausführungen.

      »» Im Zusammenhang mit der Überlegung für den Aufbau eines kleinen "Mini-CMS" für meine kleine private Homapage (lose Artikelsammlung), stehe ich (persönlich erstmals) vor der Frage, wie man ggf. einen "Caching-Mechanismus" am besten/ sinnvollsten realisiert, bzw. ob sich der Aufwand für kleine Sites überhaupt lohnt?

      Da kann ich dir Smarty empfehlen, dass bringt den Caching-Mechanismus von Haus aus mit (und ein Effektives dazu).

      Eine Anmerkung vorweg zu Smarty:
      Aus meiner Sicht (die eines ambitionierten Laiens ~ "Hobbybastler") ist Smarty der absolute "Overkill". Smarty ist sicherlich eine der umfangreichsten und besten Template-Engines, die es derzeit gibt. Aber genau das ist auch das Problem daran. Um so ein (relativ kleines) Vorhaben umsetzen zu können, muss ich schon

      • (X)HTML
      • CSS
      • Javascript
      • PHP
      • MySQL
      • Apache (Module + Konfiguration)
        einigermaßen "beherrschen", bzw. mich damit auskennen. Von daher habe ich mich bis jetzt strikt geweigert. mich zusätzlich auch noch mit einer so umfangreichen Template-Engine auseinanderzusetzen, von der ich im Endeffekt nachher nur einen Bruchteil tatsächlich verwende. Zumal ich ja auch nur eine Anwendung für meinen eigenen Gebrauch erstellen will, und nicht ein Script, dass andere User verwenden können/ sollen und dort ggf. umfangreiche Template Änderungen/ Anpassungen vornehmen können sollen.

      Smarty legt eine kopie von den erzeugten Ressourcen in ein Cache-Verzeichnis und liefert die Seiten nach dem Cachen aus diesem Verzeichnis, sprich die Inhalte werden nur einmal geparst und gespeichert.

      OK, das entspricht ja in soweit dem Vorschlag von eddi.

      Zu dem kommt, dass Smarty auch bei bereits besuchten Seiten die richtigen Header, in dem Fall 304 Not Modified mitsendet, so dass diese Seiten aus dem Browsercache geladen werden können.

      Prinzipiell klar. Ich frage mich nur gerade, woher der Server weiß, dass die Seite bereits besucht wurde?

      »» Welche Dinge kann/ sollte man grundsätzlich besser nie cachen?

      Dynamische Seiten, Bspw. Seiten mit einer Kommentarfunktion oder Gästebücher.
      Wobei man hier unterscheiden muss; wenn der User nur lesend unterwegs ist, kann er die Inhalte aus dem Cache haben, wenn er einen Beitrag schreiben möchte, muss dass Caching deaktiviert werden.

      OK.

      »» Und wie schließt man diese dann davon aus?

      Mit Smarty:

      /*

      • Wenn User was schreiben möchte oder eingelogged, nicht cachen
        */
          if (isset($_GET['write']) OR isset($_logged))
          {
            $smarty->caching = false;
          }
          else
          {
            $smarty->caching = true;
            $smarty->cache_lifetime = 18000;  // bei mir auf 5 Stunden
            $smarty->compile_check = false;
            $smarty->force_compile = false;
            $smarty->cache_modified_check = 1;
          }

      $smarty->display('my.tpl', $_SERVER['REQUEST_URI']);

      
      >   
      > Wenn ein neuer Beitrag geschrieben wurde, muss dass Cache-Verzeichnis gelöscht werden, ansonsten wird der Beitrag erst in der Seite erscheinen, wenn cache\_lifetime abgelaufen ist.  
      
      Auch klar soweit. Das kann man ja problemlos auch ohne Smarty quasi "nachbauen".  
        
      
      > »» Ob für einen rein lesenden Zugriff überhaupt eine Session angelegt werden soll, weiß ich noch nicht. Vermutlich aber schon.  
      >   
      > Für nur lesenden Zugriff würde ich das Caching bevorzugen, einmal deinem Traffic, zum anderen deinen Usern zuliebe, da Ressourcen nicht immer wieder geladen werden müssen und die Seiten zum Teil schneller ausgeliefert werden.  
      
      Hmmm ..., was mir bis jetzt immer noch nicht klar ist, ist der Punkt mit der Session.  
      Die Verwendung einer Session schließt doch die Auslieferung einer statischen Version meines Dokuments nicht aus, oder?  
        
      
      > »» Ein Login dürfte höchstwahrscheinlich u.a. für die Kommentarfunktion von Nöten sein. Je nach Seite dürfte es aller Wahrscheinlichkeit nach angepasste (dynamische) (Unter-)Menüs geben.  
      >   
      > Wie gesagt, Login und Generell Seiten, die durch die User in irgendeiner Form verändert werden können, wird das Caching nicht funktionieren.  
        
      
      > Wobei Smarty auch für diesen Fall [einige Funktionen](http://www.smarty.net/manual/de/caching.cacheable.php) mitbringt, wie Bspw. Blockweise Cachen, und teile der Seite Dynamisch halten (nur wird das dann mit den Session wieder schwierig).  
      
      Ja, das klingt doch zumindest sehr plausibel. So könnte ich also bspw. den eigentlichen Artikel aus dem (statischen) Cache holen, und bspw. nur den Kommentar-Teil dynamisch generieren und beides zusammenbauen und ausliefern.  
        
      Und bezüglich zwischenzeitlicher Aktualisierungen muss ich mir nochmal die von Eddi genannten Header Angaben (ETag, If-Match, If-Modified-Since und If-None-Match) angucken. Das habe ich noch nicht 100%ig verstanden - scheint mir aber eine mögliche Lösung für das Problem "wurde die Datei zwischenzeitlich geändert oder nicht?" zu sein.  
        
      Gruß Gunther
      
      1. hi,

        Aus meiner Sicht (die eines ambitionierten Laiens ~ "Hobbybastler") ist Smarty der absolute "Overkill".

        Eine Template-Engine wirst du ja denke ich mal eh brauchen, warum dann nicht gleich was richtiges?
        Auch wenn du nur einen Bruchteil nutzt, bietet Smarty gegenüber den meisten anderen Template-Engines nur Vorteile.
        Selbst wenn du das richtige Caching nicht verwendest, so Cached Smarty noch das eigentliche Parsen deines Scriptes und vereinfacht Intern für sich die arbeit, was der verarbeitung des Scriptes zugute kommt.

        Zumal ich ja auch nur eine Anwendung für meinen eigenen Gebrauch erstellen will, und nicht ein Script, dass andere User verwenden können/ sollen und dort ggf. umfangreiche Template Änderungen/ Anpassungen vornehmen können sollen.

        Seit dem ich Smarty kenne, nutze ich es für alles. Eine eigene Template-Engine zu schreiben finde ich zu anstrengend; zumal die Nutzung von Smarty auch für einen neueinsteiger wirklich sehr Simpel ist, und mit der Zeit lernt man dann auch weitere Funktionen, auf die man nicht mehr verzichten möchte.

        OK, das entspricht ja in soweit dem Vorschlag von eddi.

        Mit dem Unterschied, dass Smarty die Dateien mit Namen versieht, die man auf normalem Wege nicht abrufen kann;
        http://dj-tut.de/smarty/cache/%2Fbeatjuggling%2Feffekte%5E%%89%5E894%5E8944739D%%my.tpl

        Prinzipiell klar. Ich frage mich nur gerade, woher der Server weiß, dass die Seite bereits besucht wurde?

        Dass ist Kommunikation zwischen Server und Client (Browser); das habe ich aber auch noch nicht so ganz verstanden.
        Wenn der Browsercache eine Seite gecached hat, dann auch mit dem Zeitstempel, wann die ressource zuletzt geändert wurde; wenn der gleiche Browser dieses Dokument noch mal anfordert, bekommt er auch vom Server einen Zeitstempel mitgeschickt, dann kann der Browser vergleichen, wenn die angeforderte Ressource noch den gleichen Zeitstempel hat, wie im Cache, dann läd er aus dem Cache.

        Die Verwendung einer Session schließt doch die Auslieferung einer statischen Version meines Dokuments nicht aus, oder?

        Das habe ich nicht getestet, aber eine Session kannst du ja nur anlegen, wenn die Seite erfolgreich aufgerufen wird, nicht aus dem Cache; wenn der Browser die Seite aus dem Browsercache läd, weiss er nichts von einer Session, zumal Session, wenn du es nicht einstellst, das Caching deaktiviert.

        Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0

        Und bezüglich zwischenzeitlicher Aktualisierungen muss ich mir nochmal die von Eddi genannten Header Angaben (ETag, If-Match, If-Modified-Since und If-None-Match) angucken. Das habe ich noch nicht 100%ig verstanden - scheint mir aber eine mögliche Lösung für das Problem "wurde die Datei zwischenzeitlich geändert oder nicht?" zu sein.

        Du musst Korrekte Last-Modified: und Etag-Header mitsenden, und auch den Server richtig konfigurieren, was aber wirklich schwer ist, ich habe es schon probiert; Smarty regelt das von selbst, kannst du ja bei mir mal testen; zum testen brauchst du ein Tool, dass dir die generierten Header anzeigt, ich nutze Tamper-Data.
        Meine Seite -- im übrigen entspricht meine Seite allen Anschein nach dem, was du vor hast ;)

        mfg

        --
        --
  3. Ich habe für mein CMS ein Caching Mechanismus implementiert, der vom Umstand Gebrauch macht, dass Gäste/Robots keine dynamisch erzeugte Inhalte abfragen.
    Die zu cachenden Seiten müssen explizit vermerkt werden.
    Die Weiche findet auf der Ebene von .htaccess statt.
    .htaccess testet, ob kein Status-Cookie gesetzt und falls doch, der status guest oder robot ist. In diesem Fall wird die statische Seite ausgeliefert.
    Ob eine Seite sich eignet, um als statische Seite ausgeliefert zu werden, muss der CMS-Betreiber entscheiden.
    Die .htaccess Weiche bewirkt, dass für viele Seiten das Perlscript erst gar nicht gestartet werden muss. Das ist meiner Meinung nach die beste Art caching.

    mfg Beat

    --
    ><o(((°>           ><o(((°>
       <°)))o><                     ><o(((°>o
    Der Valigator leibt diese Fische