it-swarm.com.de

Tomcat 8-Auslösung - org.Apache.catalina.webresources.Cache.getResource Die Ressource kann nicht hinzugefügt werden

Ich habe gerade Tomcat von Version 7.0.52 auf 8.0.14 aktualisiert.

Ich bekomme das für viele statische Bilddateien:

org.Apache.catalina.webresources.Cache.getResource Die Ressource unter [/base/1325/WA6144-150x112.jpg] kann nicht zum Cache hinzugefügt werden, da nicht genügend Speicherplatz vorhanden ist, nachdem der abgelaufene Cache gelöscht wurde entries - erhöhen Sie die maximale Größe des Caches

Ich habe keine bestimmten Ressourceneinstellungen angegeben und diese für 7.0.52 nicht erhalten.

Ich habe in einem Fehlerbericht, der angeblich behoben wurde, erwähnt, dass dies beim Start passiert. Für mich geschieht dies nicht beim Start, sondern ständig, wenn die Ressource angefordert wird.

Hat noch jemand dieses Problem?

Der Versuch, den Cache zumindest einfach zu deaktivieren, aber ich kann kein Beispiel dafür finden, wie angegeben wird, dass der Cache nicht verwendet werden soll. Die Attribute wurden in Tomcat Version 8 aus dem Kontext entfernt. Sie haben versucht, eine Ressource hinzuzufügen, können jedoch die Konfiguration nicht richtig ausführen.

<Resource name="file" 
    cachingAllowed="false"
    className="org.Apache.catalina.webresources.FileResourceSet"
/>  

Vielen Dank.

102
iainmac999

Fügen Sie in Ihrem $CATALINA_BASE/conf/context.xml Block vor </Context> Hinzu

<Resources cachingAllowed="true" cacheMaxSize="100000" />

Weitere Informationen: http://Tomcat.Apache.org/Tomcat-8.0-doc/config/resources.html

149
Destroyica

Ich hatte das gleiche Problem beim Upgrade von Tomcat 7 auf 8: eine ununterbrochene Flut von Protokollwarnungen über den Cache.

1. Kurze Antwort

Fügen Sie dies im Context xml-Element Ihres $CATALINA_BASE/conf/context.xml Hinzu:

<!-- The default value is 10240 kbytes, even when not added to context.xml.
So increase it high enough, until the problem disappears, for example set it to 
a value 5 times as high: 51200. -->
<Resources cacheMaxSize="51200" />

Die Standardeinstellung ist 10240 (10 MB). Stellen Sie daher eine höhere Größe ein. Stellen Sie dann die optimalen Einstellungen ein, bei denen die Warnungen verschwinden. Beachten Sie, dass die Warnungen in Situationen mit hohem Verkehrsaufkommen möglicherweise erneut angezeigt werden.

1.1 Die Ursache (kurze Erklärung)

Das Problem wird dadurch verursacht, dass Tomcat seine Ziel-Cache-Größe aufgrund von Cache-Einträgen nicht erreichen kann, die kleiner sind als die TTL) dieser Einträge. Daher verfügte Tomcat nicht über genügend Cache-Einträge, die verfallen könnten Da sie zu frisch waren, konnte sie nicht genug Cache freigeben und gibt daher Warnungen aus.

Das Problem ist in Tomcat 7 nicht aufgetreten, da Tomcat 7 in dieser Situation einfach keine Warnungen ausgegeben hat. (Sie und mich dazu bringen, schlechte Cache-Einstellungen zu verwenden, ohne benachrichtigt zu werden.)

Das Problem tritt auf, wenn relativ viele HTTP-Anforderungen für Ressourcen (normalerweise statisch) in einem relativ kurzen Zeitraum empfangen werden, verglichen mit der Größe und TTL des Caches. Wenn der Cache sein Maximum erreicht (10 MB standardmäßig) Bei mehr als 95% seiner Größe mit neuen Cache-Einträgen (frisch bedeutet weniger als 5 Sekunden im Cache) erhalten Sie für jede Webressource, die Tomcat in den Cache zu laden versucht, eine Warnmeldung.

1.2 Optionale Informationen

Verwenden Sie JMX, wenn Sie cacheMaxSize auf einem laufenden Server optimieren müssen, ohne ihn neu zu starten.

Die schnellste Lösung wäre, den Cache vollständig zu deaktivieren: <Resources cachingAllowed="false" />, Aber das ist suboptimal. Erhöhen Sie daher die Größe von cacheMaxSize, wie ich gerade beschrieben habe.

2. Lange Antwort

2.1 Hintergrundinformationen

Ein WebSource ist eine Datei oder ein Verzeichnis in einer Webanwendung. Aus Performancegründen kann Tomcat WebSources zwischenspeichern. Das Maximum des statischen Ressourcencaches (alle Ressourcen insgesamt) beträgt standardmäßig 10240 KB (10 MB). Eine webResource wird in den Cache geladen, wenn die webResource angefordert wird (z. B. beim Laden eines statischen Bildes). Sie wird dann als Cache-Eintrag bezeichnet. Jeder Cache-Eintrag hat eine TTL (verbleibende Zeit). Dies ist die Zeit, zu der der Cache-Eintrag im Cache verbleiben darf. Wenn TTL abläuft, kann der Cache-Eintrag aus dem Cache entfernt werden. Der Standardwert für cacheTTL beträgt 5000 Millisekunden (5 Sekunden).

Es gibt mehr über Caching zu erzählen, aber das ist für das Problem irrelevant.

2.2 Die Ursache

Der folgende Code aus der Cache-Klasse zeigt die Caching-Richtlinie im Detail:

152  // Der Inhalt wird nicht zwischengespeichert, wir benötigen jedoch weiterhin die Metadatengröße
15  lange delta = cacheEntry . getSize ();
154 size . addAndGet (Delta);
156  wenn (size . get ()> maxSize) {
157 // Verarbeite Ressourcen ungeordnet nach Geschwindigkeit. Handelscache
158 // Effizienz (jüngere Einträge können vor älteren entfernt werden
159 // ones) für Geschwindigkeit, da dies auf dem kritischen Pfad für ist
16 // Anfragebearbeitung
161  lange targetSize =
162 maxSize * (100 - TARGET_FREE_PERCENT_GET)/100;
16  lange newSize = evict (
164 targetSize, resourceCache . values () . iterator ());
165  wenn (newSize> maxSize) {
166 // Es konnte kein ausreichender Speicherplatz für diese Ressource erstellt werden
167 // Entferne es aus dem Cache
168removeCacheEntry (path);
169 log . warn (sm . getString ("cache.addFail", path));
17 }
171 }

Beim Laden einer webResource berechnet der Code die neue Größe des Caches. Wenn die berechnete Größe größer als die Standard-Maximalgröße ist, müssen mindestens ein zwischengespeicherter Eintrag entfernt werden. Andernfalls überschreitet die neue Größe die Maximalgröße. Der Code berechnet also eine "targetSize", dh die Größe, unter der der Cache bleiben soll (als Optimum), die standardmäßig 95% des Maximums beträgt. Um diese Zielgröße zu erreichen, müssen Einträge aus dem Cache entfernt/entfernt werden. Dies geschieht mit folgendem Code:

215  privatgeländelange räumen (lange targetSize,  Iterator  < CachedResource > iter) {
217  lange now = System . currentTimeMillis ();
219  lange newSize = size . get ();
221  während (newSize> targetSize && iter . hasNext ()) {
222CachedResource resource = iter . next ();
224 // Lasse nichts ab, was innerhalb der TTL geprüft wurde
225  wenn (resource . getNextCheck ()> now) {
226  fortsetzen;
227 }
229 // Entferne den Eintrag aus dem Cache
2removeCacheEntry (resource . getWebappPath ());
232 newSize = size . get ();
2 }
235  rückkehr newSize;
236 }

Ein Cache-Eintrag wird also entfernt, wenn seine TTL abgelaufen ist und die Zielgröße noch nicht erreicht wurde.

Nach dem Versuch, den Cache durch Entfernen von Cache-Einträgen freizugeben, führt der Code Folgendes aus:

165  wenn (newSize> maxSize) {
166 // Es konnte kein ausreichender Speicherplatz für diese Ressource erstellt werden
167 // Entferne es aus dem Cache
168removeCacheEntry (path);
169 log . warn (sm . getString ("cache.addFail", path));
17 }

Wenn also nach dem Versuch, den Cache freizugeben, die maximale Größe immer noch überschritten wird, wird die Warnmeldung angezeigt, dass das Freigeben nicht möglich ist:

cache.addFail=Unable to add the resource at [{0}] to the cache for web application [{1}] because there was insufficient free space available after evicting expired cache entries - consider increasing the maximum size of the cache

2.3 Das Problem

Wie die Warnmeldung besagt, ist das Problem

nach dem Entfernen abgelaufener Cache-Einträge ist nicht genügend freier Speicherplatz verfügbar. Erhöhen Sie möglicherweise die maximale Größe des Caches

Wenn Ihre Webanwendung innerhalb kurzer Zeit (5 Sekunden) viele nicht zwischengespeicherte Webressourcen lädt (etwa maximaler Cache, standardmäßig 10 MB), wird eine Warnung angezeigt.

Der verwirrende Teil ist, dass Tomcat 7 die Warnung nicht angezeigt hat. Dies wird einfach durch diesen Tomcat 7-Code verursacht:

1606  // Neuen Eintrag zum Cache hinzufügen
1607  synchronisiert (Zwischenspeicher) {
1608 // Cache-Größe prüfen und zu große Elemente entfernen
1609  wenn ((cache . lookup (name) == null) && cache . allocate (entry.size)) {
161 cache . load (entry);
1611 }
1612 }

kombiniert mit:

231  während (zuFrei> 0) {
232  wenn (Versuche == maxAllocateIterations) {
2 // Gib auf, es werden keine Änderungen am aktuellen Cache vorgenommen
234  rückkehrfalse;
235 }

Daher gibt Tomcat 7 überhaupt keine Warnung aus, wenn der Cache nicht freigegeben werden kann, während Tomcat 8 eine Warnung ausgibt.

Wenn Sie also Tomcat 8 mit der gleichen Standard-Caching-Konfiguration wie Tomcat 7 verwenden und in Tomcat 8 Warnungen erhalten haben, war die Leistung Ihrer (und meiner) Caching-Einstellungen von Tomcat 7 ohne Warnung schlecht.

2.4 Lösungen

Es gibt mehrere Lösungen:

  1. Cache vergrößern (empfohlen)
  2. Senken Sie die TTL (nicht empfohlen)
  3. Cache-Protokollwarnungen unterdrücken (nicht empfohlen)
  4. Cache deaktivieren

2.4.1. Cache vergrößern (empfohlen)

Wie hier beschrieben: http://Tomcat.Apache.org/Tomcat-8.0-doc/config/resources.html

Durch Hinzufügen von <Resources cacheMaxSize="XXXXX" /> Innerhalb des Elements Context in $CATALINA_BASE/conf/context.xml, Wobei "XXXXX" für eine erhöhte Cachegröße in KB steht. Der Standardwert ist 10240 (10 MB). Stellen Sie daher eine höhere Größe ein.

Sie müssen für optimale Einstellungen abstimmen. Beachten Sie, dass das Problem möglicherweise erneut auftritt, wenn plötzlich mehr Verkehrs-/Ressourcenanforderungen eingehen.

Um zu vermeiden, dass der Server jedes Mal neu gestartet werden muss, wenn Sie eine neue Cachegröße ausprobieren möchten, können Sie diese mithilfe von JMX ändern, ohne einen Neustart durchführen zu müssen.

Um JMX zu aktivieren , fügen Sie dies zu $CATALINA_BASE/conf/server.xml Im Server -Element hinzu: <Listener className="org.Apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="6767" rmiServerPortPlatform="6768" /> Und laden Sie catalina-jmx-remote.jar Von https : //Tomcat.Apache.org/download-80.cgi und geben Sie es in $CATALINA_HOME/lib Ein. Verwenden Sie dann jConsole (standardmäßig mit dem Java JDK) ausgeliefert), um über JMX eine Verbindung zum Server herzustellen, und durchsuchen Sie die Einstellungen nach Einstellungen, um die Cachegröße zu erhöhen, während der Server ausgeführt wird sollte sofort wirksam werden.

2.4.2. Senken Sie die TTL (nicht empfohlen)

Verringern Sie den Wert von cacheTtl um etwas weniger als 5000 Millisekunden und stellen Sie die optimalen Einstellungen ein.

Zum Beispiel: <Resources cacheMaxSize="2000" />

Dies ist effektiv darauf zurückzuführen, dass ein Cache im RAM vorhanden ist und gefüllt wird, ohne ihn zu verwenden.

2.4.3. Cache-Protokollwarnungen unterdrücken (nicht empfohlen)

Konfigurieren Sie die Protokollierung, um die Protokollierung für org.Apache.catalina.webresources.Cache Zu deaktivieren.

Weitere Informationen zum Anmelden bei Tomcat finden Sie unter: http://Tomcat.Apache.org/Tomcat-8.0-doc/logging.html

2.4.4. Cache deaktivieren

Sie können den Cache deaktivieren, indem Sie cachingAllowed auf false setzen. <Resources cachingAllowed="false" />

Obwohl ich mich erinnern kann, dass ich in einer Beta-Version von Tomcat 8 JMX zum Deaktivieren des Caches verwendet habe. (Ich weiß nicht genau warum, aber möglicherweise liegt ein Problem beim Deaktivieren des Caches über server.xml vor.)

111
Devabc

Sie haben mehr statische Ressourcen, für die der Cache Platz hat. Sie können eine der folgenden Aktionen ausführen:

  • Vergrößern Sie den Cache
  • Verringern Sie TTL für den Cache
  • Deaktivieren Sie die Zwischenspeicherung

Weitere Informationen zu diesen Konfigurationsoptionen finden Sie in der Dokumentation .

9
Mark Thomas

Falls es jemand anderem hilft, konnte ich dieses Problem nur lösen, indem ich Folgendes an conf/logging.properties Anfügte:

org.Apache.catalina.webresources.Cache.level = SEVERE

Dies filtert die Protokolle "Die Ressource kann nicht hinzugefügt werden" heraus, die sich auf der Ebene WARNING befinden.

5
Geoffrey Booth