cachingallowed cache caching resources tomcat8

cachingallowed - Tomcat 8 throwing-org.apache.catalina.webresources.Cache.getResource No se puede agregar el recurso



cachingallowed tomcat 8 (4)

Acabo de actualizar Tomcat de la versión 7.0.52 a 8.0.14.

Estoy obteniendo esto para muchos archivos de imagen estática:

org.apache.catalina.webresources.Cache.getResource No se puede agregar el recurso en [/base/1325/WA6144-150x112.jpg] al caché porque no había suficiente espacio libre disponible después de desalojar las entradas de caché caducadas: considere aumentar el tamaño máximo del caché

No he especificado ninguna configuración de recursos en particular, y no obtuve esto para 7.0.52.

He encontrado mención de que esto sucedió al inicio en un informe de error que supuestamente se solucionó. Para mí, esto sucede no en el inicio sino constantemente cuando se solicita el recurso.

¿Alguien más tiene este problema?

Intento al menos deshabilitar el caché, pero no puedo encontrar un ejemplo de cómo especificar no usar el caché. Los atributos han pasado del contexto en Tomcat versión 8. Intenté agregar un recurso pero no puedo configurar correctamente.

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

Gracias.



Esta no es una solución en el sentido de que no resuelve las condiciones que hacen que el mensaje aparezca en los registros, pero el mensaje se puede suprimir agregando lo siguiente a conf/logging.properties :

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

Esto filtra los registros "No se puede agregar el recurso", que están en el nivel ADVERTENCIA.

En mi opinión, una WARNING no es necesariamente un error que debe abordarse, sino que puede ignorarse si se desea.


Tiene más recursos estáticos para los que el caché tiene espacio. Puede hacer uno de los siguientes:

  • Aumenta el tamaño del caché
  • Disminuya el TTL para el caché
  • Deshabilitar el almacenamiento en caché

Para obtener más detalles, consulte la http://tomcat.apache.org/tomcat-8.0-doc/config/resources.html de estas opciones de configuración.


Tuve el mismo problema al actualizar de Tomcat 7 a 8: una gran inundación continua de advertencias de registro sobre el caché.

1. Respuesta corta

Agregue esto dentro del elemento Context xml de su $CATALINA_BASE/conf/context.xml :

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

Por lo tanto, el valor predeterminado es 10240 (10 mbytes), por lo tanto, configure un tamaño superior a este. Luego, sintonice para configuraciones óptimas donde desaparezcan las advertencias. Tenga en cuenta que las advertencias pueden volver en situaciones de mayor tráfico.

1.1 La causa (breve explicación)

El problema se debe a que Tomcat no puede alcanzar su tamaño de caché de destino debido a las entradas de caché que son inferiores al TTL de esas entradas. Entonces, Tomcat no tenía suficientes entradas de caché que pudieran caducar, porque eran demasiado nuevas, por lo que no podía liberar suficiente caché y, por lo tanto, genera advertencias.

El problema no apareció en Tomcat 7 porque Tomcat 7 simplemente no emitió advertencias en esta situación. (Causando que tú y yo usemos configuraciones de caché deficientes sin ser notificados).

El problema aparece cuando se recibe una cantidad relativamente grande de solicitudes HTTP de recursos (generalmente estáticos) en un período de tiempo relativamente corto en comparación con el tamaño y TTL de la memoria caché. Si el caché está alcanzando su máximo (10 MB por defecto) con más del 95% de su tamaño con nuevas entradas de caché (nuevo significa menos de menos de 5 segundos en caché), recibirá un mensaje de advertencia por cada recurso web que Tomcat intente cargar en el caché

1.2 Información opcional

Use JMX si necesita ajustar cacheMaxSize en un servidor en ejecución sin reiniciarlo.

La solución más rápida sería deshabilitar por completo el caché: <Resources cachingAllowed="false" /> , pero eso no es óptimo, así que aumente cacheMaxSize como acabo de describir.

2. Respuesta larga

2.1 Información de antecedentes

Un WebSource es un archivo o directorio en una aplicación web. Por razones de rendimiento, Tomcat puede almacenar en caché WebSources. El máximo de la caché de recursos estáticos (todos los recursos en total) es por defecto 10240 kbytes (10 mbytes). Un webResource se carga en el caché cuando se solicita el webResource (por ejemplo, al cargar una imagen estática), luego se denomina entrada de caché. Cada entrada de caché tiene un TTL (tiempo de vida), que es el tiempo que la entrada de caché puede permanecer en el caché. Cuando caduca el TTL, la entrada de caché es elegible para ser eliminada de la caché. El valor predeterminado de cacheTTL es 5000 milisegundos (5 segundos).

Hay más que contar sobre el almacenamiento en caché, pero eso es irrelevante para el problema.

2.2 La causa

El siguiente código de la clase Cache muestra la política de almacenamiento en caché en detalle:

152 // Content will not be cached but we still need metadata size
153 long delta = cacheEntry.getSize();
154 size.addAndGet(delta);
156 if (size.get() > maxSize) {
157 // Process resources unordered for speed. Trades cache
158 // efficiency (younger entries may be evicted before older
159 // ones) for speed since this is on the critical path for
160 // request processing
161 long targetSize =
162 maxSize * (100 - TARGET_FREE_PERCENT_GET) / 100;
163 long newSize = evict(
164 targetSize, resourceCache.values().iterator());
165 if (newSize > maxSize) {
166 // Unable to create sufficient space for this resource
167 // Remove it from the cache
168 removeCacheEntry(path);
169 log.warn(sm.getString("cache.addFail", path));
170 }
171 }

Al cargar un recurso web, el código calcula el nuevo tamaño de la memoria caché. Si el tamaño calculado es mayor que el tamaño máximo predeterminado, se deben eliminar una o más entradas almacenadas en caché; de lo contrario, el nuevo tamaño excederá el máximo. Por lo tanto, el código calculará un "targetSize", que es el tamaño por debajo del cual la caché desea permanecer (como óptimo), que es por defecto el 95% del máximo. Para alcanzar este TargetSize, las entradas deben eliminarse / desalojarse del caché. Esto se hace usando el siguiente código:

215 private long evict(long targetSize, Iterator<CachedResource> iter) {
217 long now = System.currentTimeMillis();
219 long newSize = size.get();
221 while (newSize > targetSize && iter.hasNext()) {
222 CachedResource resource = iter.next();
224 // Don''t expire anything that has been checked within the TTL
225 if (resource.getNextCheck() > now) {
226 continue;
227 }
229 // Remove the entry from the cache
230 removeCacheEntry(resource.getWebappPath());
232 newSize = size.get();
233 }
235 return newSize;
236 }

Por lo tanto, una entrada de caché se elimina cuando su TTL caduca y aún no se ha alcanzado el TargetSize.

Después del intento de liberar caché desalojando las entradas de caché, el código hará lo siguiente:

165 if (newSize > maxSize) {
166 // Unable to create sufficient space for this resource
167 // Remove it from the cache
168 removeCacheEntry(path);
169 log.warn(sm.getString("cache.addFail", path));
170 }

Entonces, si después del intento de liberar caché, el tamaño aún excede el máximo, mostrará el mensaje de advertencia sobre la imposibilidad de liberar:

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 El problema

Entonces, como dice el mensaje de advertencia, el problema es

espacio libre insuficiente disponible después de desalojar las entradas de caché caducadas: considere aumentar el tamaño máximo de la caché

Si su aplicación web carga muchos recursos web no almacenados en caché (aproximadamente el máximo de caché, por defecto 10mb) en un corto tiempo (5 segundos), recibirá la advertencia.

La parte confusa es que Tomcat 7 no mostró la advertencia. Esto es simplemente causado por este código Tomcat 7:

1606 // Add new entry to cache
1607 synchronized (cache) {
1608 // Check cache size, and remove elements if too big
1609 if ((cache.lookup(name) == null) && cache.allocate(entry.size)) {
1610 cache.load(entry);
1611 }
1612 }

combinado con:

231 while (toFree > 0) {
232 if (attempts == maxAllocateIterations) {
233 // Give up, no changes are made to the current cache
234 return false;
235 }

Por lo tanto, Tomcat 7 simplemente no genera ninguna advertencia cuando no puede liberar caché, mientras que Tomcat 8 generará una advertencia.

Entonces, si está utilizando Tomcat 8 con la misma configuración de almacenamiento en caché predeterminada que Tomcat 7, y recibió advertencias en Tomcat 8, entonces su configuración (y la mía) de almacenamiento en caché de Tomcat 7 se desempeñó mal sin advertencia.

2.4 Soluciones

Existen múltiples soluciones:

  1. Aumentar caché (recomendado)
  2. Baje el TTL (no recomendado)
  3. Suprimir advertencias de registro de caché (no recomendado)
  4. Deshabilitar caché

2.4.1 Aumentar caché (recomendado)

Como se describe aquí: http://tomcat.apache.org/tomcat-8.0-doc/config/resources.html

Al agregar <Resources cacheMaxSize="XXXXX" /> dentro del elemento Context en $CATALINA_BASE/conf/context.xml , donde "XXXXX" representa un mayor tamaño de caché, especificado en kbytes. El valor predeterminado es 10240 (10 mbyte), por lo tanto, configure un tamaño superior a este.

Tendrá que sintonizar para una configuración óptima. Tenga en cuenta que el problema puede reaparecer cuando de repente tiene un aumento en las solicitudes de tráfico / recursos.

Para evitar tener que reiniciar el servidor cada vez que desee probar un nuevo tamaño de caché, puede cambiarlo sin reiniciar utilizando JMX.

Para habilitar JMX , agregue esto a $CATALINA_BASE/conf/server.xml dentro del elemento Server : <Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="6767" rmiServerPortPlatform="6768" /> y descargue catalina-jmx-remote.jar de https://tomcat.apache.org/download-80.cgi y ponerlo en $CATALINA_HOME/lib . Luego, use jConsole (incluido de forma predeterminada con Java JDK) para conectarse a través de JMX al servidor y verifique la configuración para aumentar el tamaño de la memoria caché mientras el servidor se está ejecutando. Los cambios en estas configuraciones deberían tener efecto inmediatamente.

2.4.2 Baje el TTL (no recomendado)

cacheTtl valor de cacheTtl en algo inferior a 5000 milisegundos y ajuste para obtener una configuración óptima.

Por ejemplo: <Resources cacheMaxSize="2000" />

Esto se reduce a tener y llenar un caché en ram sin usarlo.

2.4.3 Suprimir advertencias de registro de caché (no recomendado)

Configure el registro para deshabilitar el registrador para org.apache.catalina.webresources.Cache .

Para obtener más información sobre cómo iniciar sesión en Tomcat: http://tomcat.apache.org/tomcat-8.0-doc/logging.html

2.4.4 Deshabilitar caché

Puede deshabilitar el caché configurando http://tomcat.apache.org/tomcat-8.0-doc/config/resources.html en false . <Resources cachingAllowed="false" />

Aunque puedo recordar que en una versión beta de Tomcat 8, estaba usando JMX para deshabilitar el caché. (No estoy seguro de por qué exactamente, pero puede haber un problema al deshabilitar el caché a través de server.xml).