web-dev-qa-db-fra.com

Tomcat 8 jetant - org.Apache.catalina.webresources.Cache.getResource Impossible d'ajouter la ressource.

Je viens de mettre à niveau Tomcat de la version 7.0.52 à la version 8.0.14.

Je reçois ceci pour beaucoup de fichiers images statiques:

org.Apache.catalina.webresources.Cache.getResource Impossible d'ajouter la ressource sur [/base/1325/WA6144-150x112.jpg] au cache car l'espace disponible était insuffisant après l'éviction du cache expiré. entrées - envisagez d'augmenter la taille maximale du cache

Je n'ai spécifié aucun paramètre de ressource particulier et je ne l'ai pas obtenu pour 7.0.52.

J'ai trouvé la mention de ce qui se passe au démarrage dans un rapport de bogue qui aurait été corrigé. Pour moi, cela ne se produit pas au démarrage, mais constamment lorsque la ressource est demandée.

Quelqu'un d'autre a ce problème?

Essayer au moins de simplement désactiver le cache, mais je ne trouve pas d'exemple pour indiquer comment ne pas utiliser le cache. Les attributs ont quitté le contexte de Tomcat version 8. J'ai essayé d'ajouter une ressource, mais impossible d'obtenir la configuration correcte.

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

Merci.

102
iainmac999

Dans votre $CATALINA_BASE/conf/context.xml ajouter un bloc ci-dessous avant </Context>

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

Pour plus d'informations: http://Tomcat.Apache.org/Tomcat-8.0-doc/config/resources.html

149
Destroyica

J'ai eu le même problème lors de la mise à niveau de Tomcat 7 à 8: un flot important d'avertissements de journalisation concernant le cache.

1. Réponse courte

Ajoutez ceci dans l'élément Context xml de votre $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" />

Donc, la valeur par défaut est 10240 (10 Mo), définissez donc une taille supérieure à celle-ci. Alors accordez pour des réglages optimaux où les avertissements disparaissent. Notez que les avertissements peuvent revenir dans des situations de trafic intense.

1.1 La cause (brève explication)

Le problème est dû au fait que Tomcat n'a pas pu atteindre la taille de son cache cible en raison d'entrées de cache inférieures au TTL de ces entrées. Tomcat ne disposait donc pas d'assez d'entrées dans le cache pour pouvoir expirer, car elles étaient trop récentes, de sorte qu'il ne pouvait pas libérer suffisamment de cache et générait ainsi des avertissements.

Le problème n’apparaissait pas dans Tomcat 7, car Tomcat 7 n’avait simplement pas émis d’avertissements dans cette situation. (Vous et moi sommes obligés d'utiliser de mauvais paramètres de cache sans en être averti.)

Le problème apparaît lors de la réception d'un nombre relativement important de demandes HTTP de ressources (généralement statiques) sur une période relativement courte par rapport à la taille et à TTL du cache. Si le cache atteint son maximum (10 Mo par défaut) avec plus de 95% de sa taille avec de nouvelles entrées de cache (frais signifie moins de 5 secondes dans le cache), vous recevrez un message d'avertissement pour chaque ressource Web que Tomcat essaie. charger dans le cache.

1.2 Informations facultatives

Utilisez JMX si vous devez adapter cacheMaxSize sur un serveur en cours d'exécution sans le redémarrer.

La solution la plus rapide consisterait à désactiver complètement le cache: <Resources cachingAllowed="false" />, mais ce n'est pas optimal, augmentez donc cacheMaxSize comme je viens de le décrire.

2. Réponse longue

2.1 Informations générales

Un WebSource est un fichier ou un répertoire dans une application Web. Pour des raisons de performances, Tomcat peut mettre en cache des sources Web. Le maximum du cache de ressources statiques (toutes les ressources au total) est par défaut de 10240 Ko (10 Mo). Une ressource WebResource est chargée dans le cache lorsque la requête WebResource est demandée (par exemple, lors du chargement d'une image statique), elle est ensuite appelée une entrée de cache. Chaque entrée de cache a un TTL (durée de vie), qui correspond au temps pendant lequel l'entrée de cache est autorisée à rester dans le cache. Lorsque le TTL expire, l'entrée du cache est éligible pour être supprimée du cache. La valeur par défaut de la propriété cacheTTL est 5 000 millisecondes (5 secondes).

Il y a plus à dire sur la mise en cache, mais cela n'a aucune importance pour le problème.

2.2 La cause

Le code suivant de la classe de cache montre la stratégie de mise en cache en détail:

152  // Le contenu ne sera pas mis en cache, mais nous avons toujours besoin de la taille des métadonnées.
153  longue delta = cacheEntry. getSize ();
154 taille. addAndGet (delta);
156  si (taille. get ()> maxSize) {
157 // Traite les ressources non ordonnées pour la vitesse. Cache de métiers
158 // efficacité (les entrées les plus jeunes peuvent être expulsées avant les plus âgées)
159 //) pour la vitesse, car il s'agit du chemin critique pour
160 // traitement de la demande
161  longue targetSize =
162 maxSize * (100 - TARGET_FREE_PERCENT_GET)/100;
163  longue newSize = expulser (
164 targetSize, resourceCache. valeurs (). itérateur ());
165  si (newSize> maxSize) {
166 // Impossible de créer un espace suffisant pour cette ressource.
167 // Supprimez-le du cache
168removeCacheEntry (chemin);
169 log. warn (sm. getString ("cache.addFail" , chemin));
170 }
171 }

Lors du chargement d'une ressource Web, le code calcule la nouvelle taille du cache. Si la taille calculée est supérieure à la taille maximale par défaut, vous devez supprimer une ou plusieurs entrées en cache, sinon la nouvelle taille dépassera la taille maximale. Donc, le code va calculer un "targetSize", qui est la taille sous laquelle le cache veut rester (optimum), qui est par défaut 95% du maximum. Pour atteindre cette taille cible, les entrées doivent être supprimées/expulsées du cache. Ceci est fait en utilisant le code suivant:

215  privélongue expulser(longue targetSize,  Itérateur  < CachedResource > iter) {
217 ​​  longue now = System. currentTimeMillis ();
219  longue newSize = taille. get ();
221  tandis que (newSize> targetSize && iter. hasNext ()) {
222CachedResource resource = iter. next ();
224 // Ne pas expirer quoi que ce soit qui a été vérifié dans le TTL
225  si (ressource. getNextCheck ()> maintenant) {
226  continuez;
227 }
229 // Supprimer l'entrée du cache
230removeCacheEntry (ressource. getWebappPath ());
232 newSize = size. get ();
233 }
235  revenir newSize;
236 }

Ainsi, une entrée de cache est supprimée lorsque sa TTL est expirée et que la taille cible n’a pas encore été atteinte.

Après la tentative de libération du cache en expulsant les entrées du cache, le code fera:

165  si (newSize> maxSize) {
166 // Impossible de créer un espace suffisant pour cette ressource.
167 // Supprimez-le du cache
168removeCacheEntry (chemin);
169 log. warn (sm. getString ("cache.addFail" , chemin));
170 }

Donc, si après la tentative de libération du cache, la taille dépasse toujours le maximum, le message d'avertissement indiquant qu'il est impossible de libérer est affiché:

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 Le problème

Donc, comme le message d'avertissement dit, le problème est

espace libre insuffisant après l'éviction des entrées de cache expirées - envisagez d'augmenter la taille maximale du cache

Si votre application Web charge de nombreuses ressources Web non mises en cache (environ le cache par défaut, 10 Mo par défaut) en un court laps de temps (5 secondes), vous obtenez alors l'avertissement.

La partie déroutante est que Tomcat 7 n'a pas montré l'avertissement. Ceci est simplement causé par ce code Tomcat 7:

1606  // Ajoute une nouvelle entrée à la mémoire cache
1607  synchronisé (cache) {
1608 // Vérifie la taille du cache et supprime les éléments s'ils sont trop gros
1609  si ((cache. lookup (name) == nul) && cache. allocate (entry.size)) {
1610 cache. charger (entrée);
1611 }
1612 }

combiné avec:

231  tandis que (toFree> 0) {
232  si (tentatives == maxAllocateIterations) {
233 // Abandonnez, aucune modification n'est apportée au cache actuel.
234  revenirfalse;
235 }

Tomcat 7 ne génère donc aucun avertissement lorsqu'il est incapable de libérer le cache, alors que Tomcat 8 émet un avertissement.

Par conséquent, si vous utilisez Tomcat 8 avec la même configuration de mise en cache par défaut que Tomcat 7 et que vous recevez des avertissements dans Tomcat 8, vos paramètres de mise en cache (et les miens) de Tomcat 7 se comportaient mal sans avertissement.

2.4 Solutions

Il y a plusieurs solutions:

  1. Augmenter le cache (recommandé)
  2. Abaissez le TTL (non recommandé)
  3. Supprimer les avertissements du journal de cache (non recommandé)
  4. Désactiver le cache

2.4.1. Augmenter le cache (recommandé)

Comme décrit ici: http://Tomcat.Apache.org/Tomcat-8.0-doc/config/resources.html

En ajoutant <Resources cacheMaxSize="XXXXX" /> dans l'élément Context dans $CATALINA_BASE/conf/context.xml, où "XXXXX" correspond à une taille de cache accrue, spécifiée en kilo-octets. La valeur par défaut est 10240 (10 Mo), définissez donc une taille supérieure à celle-ci.

Vous devrez régler pour des réglages optimaux. Notez que le problème peut revenir lorsque vous avez soudainement une augmentation du trafic/des demandes de ressources.

Pour éviter de devoir redémarrer le serveur à chaque fois que vous souhaitez essayer une nouvelle taille de cache, vous pouvez le modifier sans redémarrer à l'aide de JMX.

Pour activer JMX , ajoutez ceci à $CATALINA_BASE/conf/server.xml dans l'élément Server: <Listener className="org.Apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="6767" rmiServerPortPlatform="6768" /> et téléchargez catalina-jmx-remote.jar depuis https : //Tomcat.Apache.org/download-80.cgi et le mettre dans $CATALINA_HOME/lib. Ensuite, utilisez jConsole (livré par défaut avec le JDK Java.) pour vous connecter via JMX au serveur et recherchez dans les paramètres les paramètres permettant d'augmenter la taille du cache pendant l'exécution du serveur. Les modifications de ces paramètres devraient prendre effet immédiatement.

2.4.2. Abaissez le TTL (non recommandé)

Réduisez la valeur cacheTtl de moins de 5 000 millisecondes et réglez-la pour obtenir les meilleurs paramètres.

Par exemple: <Resources cacheMaxSize="2000" />

Cela revient effectivement à avoir et à remplir un cache dans la RAM sans l’utiliser.

2.4.3. Supprimer les avertissements du journal de cache (non recommandé)

Configurez la journalisation pour désactiver le consignateur pour org.Apache.catalina.webresources.Cache.

Pour plus d'informations sur la connexion à Tomcat: http://Tomcat.Apache.org/Tomcat-8.0-doc/logging.html

2.4.4. Désactiver le cache

Vous pouvez désactiver le cache en définissant cachingAllowed sur false. <Resources cachingAllowed="false" />

Bien que je me souvienne de cela, dans une version bêta de Tomcat 8, j’utilisais JMX pour désactiver le cache. (Vous ne savez pas exactement pourquoi, mais il peut y avoir un problème avec la désactivation du cache via server.xml.)

111
Devabc

Vous avez plus de ressources statiques que le cache a de la place. Vous pouvez effectuer l’une des opérations suivantes:

  • Augmenter la taille du cache
  • Diminuer le TTL pour le cache
  • Désactiver la mise en cache

Pour plus de détails, voir documentation pour ces options de configuration.

9
Mark Thomas

Au cas où cela aiderait quelqu'un d'autre, la seule façon pour moi de résoudre ce problème a été d'ajouter ce qui suit à conf/logging.properties:

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

Ceci filtre les journaux "Impossible d'ajouter la ressource", qui sont au niveau AVERTISSEMENT.

5
Geoffrey Booth