CachingServlet im Detail
EH-Cache: The Most Widely Used Java Cache
Stabilität erreichten wir durch die Minimierung der Requests, die an Helma weitergereicht werden, Performance durch Caching. Als Cache-Engine verwenden wir EH-Cache. Dieses großartige Stück Software ist nicht nur beim Caching im Einsatz, wir verwenden es bei den verschiedensten rechen- oder zeitaufwändigen Dingen.
Funktionsweise
Als erster Schritt wird überprüft, ob eine im Request angeforderte HTML-Seite bereits in einer gültigen, gecachten Version vorhanden ist. Im Idealfall, der bei uns in mehr als 90% der Fälle zutrifft, liefert das CachingServlet dafür direkt die gecachte Version aus dem Speicher zurück.
Ist ein Cache-Eintrag nicht mehr up to date, wird der erste Request, der diese Seite anforderte, zur Helma-Applikation durchgelassen, um so den Cacheeintrag zu erneuern. Alle weiteren werden in der Zwischenzeit mit der bereits vorhandenen Version beliefert. Erst nachdem der erste Request aus der Applikation zurückkehrt, werden alle nachfolgenden Requests mit der neuesten Version beliefert.
Sollte es noch keinen Cache-Eintrag geben, wird ebenfalls nur ein Request durchgelassen. In diesem Fall müssen jedoch die Folgerequests warten, bis der erste Request abgeschlossen wurde. Anschließend wird dessen Ergebnis auch an alle anderen, bis dahin wartenden Requests ausgeliefert und als Cache-Eintrag abgelegt.
Was und wie wird gecached?
Wir cachen sowohl die unkomprimierte Rohfassung, als auch die fertig komprimierte Version einer Response. Durch diese Vorgangsweise erreichten wir die effizienteste Möglichkeit um Seiten auszuliefern. Im Idealfall werden so alle Requests gecached.
Da es immer Teile einer Website gibt, die nicht – oder unterschiedlich lange – gecached werden dürfen, gibt es hierfür die Möglichkeit der Konfiguration:
Für jeden HTTP-Response-Code kann man getrennt festlegen, wie lange eine Seite im Cache verweilt. Zum Beispiel kann man ein „404 Not Found“ für kürzere Zeit cachen, ein „301 Moved Permanently“ umso länger.
Für „HTTP 200 OK“ Responses kann man über regular Expressions aufgrund ihrer URL getrennt festlegen, ob und wie lange diese Seiten ihre Gültigkeit behalten.
Den Überblick bewahren
Natürlich will man nicht nur oberflächliche Effizienz, man benötigt auch Kontrolle, um diese Effizienz überprüfen zu können. Für diese Zwecke gibt es eine simple Schnittstelle. Über eine geschützte Adresse erhält man dann folgende Auswertung:
=== STATISTICS === Cache hits: 569334 Cache misses: 25596 Cache hit rate: 96% Elements in cache: 2946 Elements in memory: 1500 Elements on disk: 1500 Average retrieval: 0.048412707 ms Evictions: 0 Hits in memory: 520782 Hits on disk: 48552 Requestqueue size: 0 === CONFIGURATION EH-Cache === Name: default Enabled: true Disk store path: /fs/path/... Disk persistent: true Overflow to disk: true Max. elements in memory: 1500 Max. elements on disk: 1500 Disk spool buffer: 30 MB === CONFIGURATION servlet === Enabled: true maxQueueSize: 4000 blockingTimeout(URL): 5000 (http://...) Update EHcache-config: false Adminadresses: Responsecode-TTL-values: 307 -> 600 404 -> 60 303 -> 600 500 -> 0 302 -> 600 301 -> 3600 URL-Part-exclusions: Cachetime-mappings: "^/helma/xxxxx/_.*" -> -1 "^.*$" -> 20
Man sieht hier auch die derzeit gültigen Konfigurationsparameter, die wir hier beispielhaft mit auflisten. Unterschiedliche Response-Codes werden unterschiedlich lange gecached. Alle „200 OK“-Antworten werden noch über eine oder mehrere regulärer Ausdrücke einer Cache-Time zugewiesen.
Munin zur Erstellung von Graphen leicht gemacht
Um das ganze noch abzurunden gibt es wichtige Kennzahlen auch noch als maschinenlesbares Format, um Graphen wie wir sie hier in diesem Artikel verwenden zu erzeugen. Das sieht dann wie Folgt aus:
total.value 600766 hits.value 574691 misses.value 26075 hitRate.value 96 memoryElements.value 1500 diskElements.value 1500 retrievalAvg.value 0.048760116 queueSize.value 0
Manfred Andres,