Ho appena aggiornato Tomcat dalla versione 7.0.52 alla 8.0.14.
Sto ottenendo questo per un sacco di file di immagine statici:
org.Apache.catalina.webresources.Cache.getResource Impossibile aggiungere la risorsa in [/base/1325/WA6144-150x112.jpg] alla cache perché non c'era spazio disponibile sufficiente dopo aver rimosso le voci della cache scadute: prendere in considerazione l'aumento della dimensione massima della cache
Non ho specificato alcuna particolare impostazione di risorse, e non ho avuto questo per 7.0.52.
Ho trovato menzione di ciò che accade all'avvio in una segnalazione di bug che è stata presumibilmente corretta. Per me questo sta accadendo non all'avvio, ma costantemente quando viene richiesta la risorsa.
Qualcun altro ha questo problema?
Cercando di disabilitare almeno la cache, ma non riesco a trovare un esempio su come specificare di non utilizzare la cache. Gli attributi sono passati dal contesto in Tomcat versione 8. Ho provato ad aggiungere una risorsa ma non riesco a ottenere la configurazione giusta.
<Resource name="file"
cachingAllowed="false"
className="org.Apache.catalina.webresources.FileResourceSet"
/>
Grazie.
Nel tuo $CATALINA_BASE/conf/context.xml
aggiungi il blocco sottostante prima di </Context>
<Resources cachingAllowed="true" cacheMaxSize="100000" />
Per maggiori informazioni: http://Tomcat.Apache.org/Tomcat-8.0-doc/config/resources.html
Ho avuto lo stesso problema durante l'aggiornamento da Tomcat 7 a 8: un flusso continuo di allarmi persistenti sulla cache.
Aggiungi questo all'interno dell'elemento Context
xml del tuo $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" />
Quindi il default è 10240
(10 mbyte), quindi imposta una dimensione più alta di questa. Quindi sintonizzare le impostazioni ottimali in cui gli avvisi scompaiono. Si noti che gli avvisi potrebbero tornare in situazioni di traffico più elevato.
Il problema è causato dal fatto che Tomcat non è in grado di raggiungere la dimensione della cache di destinazione a causa di voci della cache inferiori a TTL di tali voci. Quindi Tomcat non aveva abbastanza voci della cache che poteva scadere, perché erano troppo fresche, quindi non poteva liberare abbastanza cache e quindi emettere avvisi.
Il problema non è apparso in Tomcat 7 perché Tomcat 7 semplicemente non ha emesso avvisi in questa situazione. (Fare in modo che tu e io usiamo impostazioni della cache scadenti senza essere avvisati).
Il problema si verifica quando si riceve una grande quantità relativa di richieste HTTP per risorse (in genere statiche) in un periodo di tempo relativamente breve rispetto alla dimensione e TTL della cache. Se la cache raggiunge il massimo (10mb per impostazione predefinita) con più del 95% delle sue dimensioni con nuove voci della cache (fresche significa meno di 5 secondi in cache), verrà visualizzato un messaggio di avviso per ogni risorsa Web che Tomcat tenta caricare nella cache.
Utilizzare JMX se è necessario sintonizzare cacheMaxSize su un server in esecuzione senza riavviarlo.
La soluzione più rapida sarebbe disabilitare completamente la cache: <Resources cachingAllowed="false" />
, ma non è ottimale, quindi aumenta cacheMaxSize come ho appena descritto.
A WebSource è un file o una directory in un'applicazione web. Per motivi di prestazioni, Tomcat può memorizzare nella cache WebSources. Il massimo della cache delle risorse statiche (tutte le risorse in totale) è di default 10240 kbyte (10 mbyte). Una risorsa Web viene caricata nella cache quando viene richiesta la risorsa Web (ad esempio quando si carica un'immagine statica), quindi viene chiamata voce della cache. Ogni voce della cache ha un TTL (time to live), che è il tempo in cui la voce della cache può rimanere nella cache. Quando scade il TTL, la voce cache è idonea per essere rimossa dalla cache. Il valore predefinito di cacheTTL è 5000 millisecondi (5 secondi).
C'è altro da dire sul caching, ma questo è irrilevante per il problema.
Il seguente codice della classe Cache mostra in dettaglio la politica di memorizzazione nella cache:
152 // Il contenuto non verrà memorizzato nella cache, ma abbiamo ancora bisogno della dimensione dei metadati
153 lungo delta = cacheEntry. getSize ();
154 dimensione. addAndGet (delta);
156 se (dimensione. get ()> maxSize) {
157 // Elabora risorse non ordinate per la velocità. Cache commerciale
158 // efficienza (le voci più giovani possono essere sfrattate prima di età avanzata
159 // ones) per la velocità poiché questo è sul percorso critico per
160 // richiesta elaborazione
161 lungo targetSize =
162 maxSize * (100 - TARGET_FREE_PERCENT_GET)/100;
163 lungo newSize = sfratto (
164 targetSize, resourceCache. valori (). iteratore ());
165 se (newSize> maxSize) {
166 // Impossibile creare spazio sufficiente per questa risorsa
167 // Rimuoverlo dalla cache
168removeCacheEntry (percorso);
169 log. warn (sm. getString ("cache.addFail", percorso));
170 }
171 }
Quando si carica una risorsa Web, il codice calcola la nuova dimensione della cache. Se la dimensione calcolata è maggiore della dimensione massima predefinita, è necessario rimuovere una o più voci memorizzate nella cache, altrimenti la nuova dimensione supererà il limite massimo. Quindi il codice calcolerà un "target size", che è la dimensione in cui la cache vuole rimanere (come un ottimo), che è di default il 95% del massimo. Per raggiungere questo targetSize, le voci devono essere rimosse/sfrattate dalla cache. Questo viene fatto usando il seguente codice:
215 privatolungo sfrattare(lungo targetSize, Iterator < CachedResource > iter) {
217 lungo now = System. currentTimeMillis ();
219 lungo newSize = size. get ();
221 mentre (newSize> targetSize && iter. hasNext ()) {
222CachedResource resource = iter. accanto ();
224 // Non fa scadere nulla che è stato controllato all'interno del TTL
225 se (risorsa. getNextCheck ()> ora) {
226 continua;
227 }
229 // Rimuovi la voce dalla cache
230removeCacheEntry (risorsa. getWebappPath ());
232 newSize = size. get ();
233 }
235 ritorno newSize;
236 }
Quindi una voce cache viene rimossa quando il suo TTL è scaduto e il targetSize non è stato ancora raggiunto.
Dopo aver tentato di liberare la cache rimuovendo le voci della cache, il codice eseguirà:
165 se (newSize> maxSize) {
166 // Impossibile creare spazio sufficiente per questa risorsa
167 // Rimuoverlo dalla cache
168removeCacheEntry (percorso);
169 log. warn (sm. getString ("cache.addFail", percorso));
170 }
Quindi, se dopo il tentativo di liberare la cache, la dimensione supera ancora il massimo, mostrerà il messaggio di avviso relativo all'impossibilità di liberare:
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
Quindi, come dice il messaggio di avviso, il problema è
spazio disponibile insufficiente dopo aver rimosso le voci della cache scadute - considerare di aumentare la dimensione massima della cache
Se l'applicazione Web carica un sacco di risorse Web non collegate (circa il massimo di cache, per impostazione predefinita 10mb) entro un breve periodo di tempo (5 secondi), verrà visualizzato l'avviso.
La parte confusa è che Tomcat 7 non ha mostrato l'avviso. Questo è semplicemente causato da questo codice Tomcat 7:
1606 // Aggiungi una nuova voce alla cache
1607 sincronizzato (cache) {
1608 // Controlla la dimensione della cache e rimuovi gli elementi se troppo grandi
1609 se ((cache. ricerca (nome) == nullo) && cache. allocate (entry.size)) {
1610 cache. load (voce);
1611 }
1612 }
combinati con:
231 mentre (toFree> 0) {
232 se (tentativi == maxAllocateIterations) {
233 // Rinuncia, non vengono apportate modifiche alla cache corrente
234 ritornofalse;
235 }
Quindi Tomcat 7 semplicemente non emette alcun avviso quando non è in grado di liberare la cache, mentre Tomcat 8 emette un avviso.
Quindi, se stai utilizzando Tomcat 8 con la stessa configurazione di cache predefinita di Tomcat 7 e ricevi avvisi in Tomcat 8, le tue (e mie) impostazioni di cache di Tomcat 7 si stanno comportando male senza preavviso.
Ci sono più soluzioni:
Come descritto qui: http://Tomcat.Apache.org/Tomcat-8.0-doc/config/resources.html
Aggiungendo <Resources cacheMaxSize="XXXXX" />
all'interno dell'elemento Context
in $CATALINA_BASE/conf/context.xml
, dove "XXXXX" rappresenta una dimensione della cache maggiore, specificata in kbyte. Il valore predefinito è 10240 (10 mbyte), quindi impostare una dimensione più alta di questa.
Dovrai sintonizzare per le impostazioni ottimali. Si noti che il problema può tornare quando si ha improvvisamente un aumento delle richieste di traffico/risorse.
Per evitare di dover riavviare il server ogni volta che si desidera provare una nuova dimensione della cache, è possibile modificarla senza riavviare utilizzando JMX.
Per abilitare JMX , aggiungere questo a $CATALINA_BASE/conf/server.xml
all'interno dell'elemento Server
: <Listener className="org.Apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="6767" rmiServerPortPlatform="6768" />
e scaricare catalina-jmx-remote.jar
da https: // Tomcat . Apache.org/download-80.cgi e inseriscilo in $CATALINA_HOME/lib
. Quindi utilizzare jConsole (fornito di default con Java JDK) per connettersi tramite JMX al server e cercare tra le impostazioni per aumentare le dimensioni della cache mentre il server è in esecuzione. Le modifiche a queste impostazioni dovrebbero avere effetto immediato.
Abbassa il valore cacheTtl
di qualcosa di inferiore a 5000 millisecondi e ottimizza le impostazioni ottimali.
Ad esempio: <Resources cacheMaxSize="2000" />
Questo deriva in effetti dall'avere e riempire una cache in ram senza usarla.
Configura la registrazione per disabilitare il logger per org.Apache.catalina.webresources.Cache
.
Per ulteriori informazioni sull'accesso a Tomcat: http://Tomcat.Apache.org/Tomcat-8.0-doc/logging.html
Puoi disabilitare la cache impostando cachingAllowed
a false
. <Resources cachingAllowed="false" />
Anche se posso ricordare che in una versione beta di Tomcat 8, stavo usando JMX per disabilitare la cache. (Non sono sicuro del perché esattamente, ma potrebbe esserci un problema con la disattivazione della cache tramite server.xml.)
Nel caso in cui aiuti qualcun altro, l'unico modo in cui sono riuscito a risolvere questo problema è stato quello di aggiungere quanto segue a conf/logging.properties
:
org.Apache.catalina.webresources.Cache.level = SEVERE
Questo filtra i registri "Impossibile aggiungere la risorsa", che sono al livello ATTENZIONE.