Tive o mesmo problema ao atualizar do Tomcat 7 para o 8: uma grande inundação contínua de avisos de log sobre o cache.
1. Resposta curta
Adicione-o ao Contextelemento xml do seu $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" />
Portanto, o padrão é 10240(10 mbyte), então defina um tamanho maior do que isso. Em seguida, ajuste as configurações ideais onde os avisos desaparecem. Observe que os avisos podem voltar em situações de tráfego intenso.
1.1 A causa (breve explicação)
O problema é causado pelo fato de o Tomcat não conseguir atingir seu tamanho de cache de destino devido às entradas de cache que são menores que o TTL dessas entradas. Portanto, o Tomcat não tinha entradas de cache suficientes para que pudesse expirar, porque eram muito recentes, de modo que não poderia liberar cache suficiente e, portanto, gera avisos.
O problema não apareceu no Tomcat 7 porque o Tomcat 7 simplesmente não emitia avisos nessa situação. (Fazendo você e eu usarmos configurações de cache insatisfatórias sem sermos notificados.)
O problema aparece ao receber uma quantidade relativamente grande de solicitações HTTP para recursos (geralmente estáticos) em um período de tempo relativamente curto em comparação com o tamanho e o TTL do cache. Se o cache estiver atingindo seu máximo (10 MB por padrão) com mais de 95% de seu tamanho com novas entradas de cache (novo significa menos de 5 segundos no cache), você receberá uma mensagem de aviso para cada recurso da web que o Tomcat tenta para carregar no cache.
1.2 Informação opcional
Use JMX se precisar ajustar cacheMaxSize em um servidor em execução sem reiniciá-lo.
A correção mais rápida seria desabilitar completamente o cache <Resources cachingAllowed="false" />:, mas isso está abaixo do ideal, então aumente cacheMaxSize como acabei de descrever.
2. Resposta longa
2.1 Informações básicas
Um WebSource é um arquivo ou diretório em um aplicativo da web. Por motivos de desempenho, o Tomcat pode armazenar WebSources em cache. O máximo do cache de recursos estáticos (todos os recursos no total) é, por padrão, 10240 kbyte (10 mbyte). Um webResource é carregado no cache quando o webResource é solicitado (por exemplo, ao carregar uma imagem estática) e é então chamado de entrada de cache. Cada entrada de cache possui um TTL (tempo de vida), que é o tempo que a entrada de cache pode permanecer no cache. Quando o TTL expira, a entrada do cache é elegível para ser removida do cache. O valor padrão do cacheTTL é 5000 milissegundos (5 segundos).
Há mais informações sobre o cache, mas isso é irrelevante para o problema.
2.2 A causa
O código a seguir da classe Cache mostra a política de cache em detalhes:
152 // O conteúdo não será armazenado em cache, mas ainda precisamos do tamanho dos metadados
153 long delta = cacheEntry. getSize (); Tamanho
154 . addAndGet (delta);
156 if (size. Get ()> maxSize) {
157 // Processar recursos não ordenados para velocidade. Trades cache
158 // eficiência (entradas mais novas podem ser removidas antes das
159 // mais antigas ) para velocidade, uma vez que este é o caminho crítico para
160 // processamento de solicitação
161 long targetSize =
162 maxSize * (100 - TARGET_FREE_PERCENT_GET) / 100;
163 longo newSize = despejar (
164 . TargetSize, resourceCache valores (). Iteração ());
165 if (newSize> maxSize) {
166 // Não é possível criar espaço suficiente para este recurso
167 // Remova-o do cache
168 removeCacheEntry (path);
169 log. warn (sm. getString ("cache.addFail", caminho));
170 }
171 }
Ao carregar um webResource, o código calcula o novo tamanho do cache. Se o tamanho calculado for maior do que o tamanho máximo padrão, uma ou mais entradas em cache devem ser removidas, caso contrário, o novo tamanho excederá o máximo. Assim, o código calculará um "targetSize", que é o tamanho que o cache deseja manter (como ideal), que é por padrão 95% do máximo. Para alcançar este targetSize, as entradas devem ser removidas / removidas do cache. Isso é feito usando o seguinte código:
215 despejo longo privado ( long targetSize, Iterator < CachedResource > iter) { 217 long now = System. currentTimeMillis (); 219 longo newSize = size. get (); 221 while (newSize> targetSize && iter. HasNext ()) { 222 CachedResource resource = iter. próximo (); 224 // Não expira nada que foi verificado no TTL 225 if (resource. GetNextCheck ()> now) { 226
continue ;
227 }
229 // Remova a entrada do cache
230 removeCacheEntry (resource. GetWebappPath ());
232 newSize = size. get ();
233 }
235 retornar novoTamanho;
236 }
Portanto, uma entrada de cache é removida quando seu TTL expira e o targetSize ainda não foi alcançado.
Após a tentativa de liberar o cache removendo as entradas do cache, o código fará:
165 if (newSize> maxSize) {
166 // Não é possível criar espaço suficiente para este recurso
167 // Remova-o do cache
168 removeCacheEntry (path);
169 log. warn (sm. getString ("cache.addFail", caminho));
170 }
Portanto, se após a tentativa de liberar o cache, o tamanho ainda ultrapassar o máximo, será exibida a mensagem de aviso sobre a impossibilidade 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 O problema
Como diz a mensagem de aviso, o problema é
espaço livre insuficiente disponível após a remoção de entradas de cache expiradas - considere aumentar o tamanho máximo do cache
Se o seu aplicativo da web carregar muitos webResources não armazenados em cache (no máximo de cache, por padrão 10 MB) em um curto período (5 segundos), você receberá o aviso.
A parte confusa é que o Tomcat 7 não mostrou o aviso. Isso é causado simplesmente por este código Tomcat 7:
1606 // Adicionar nova entrada ao cache
1607 synchronized (cache) {
1608 // Verificar o tamanho do cache e remover elementos se forem muito grandes
1609 if ((cache. Lookup (name) == null ) && cache. Alocar (entry.size) ) {
1610 cache. carregar (entrada);
1611 }
1612 }
combinado com:
231 while (toFree> 0) {
232 if (tentativas == maxAllocateIterations) {
233 // Desista, nenhuma mudança é feita no cache atual
234 return false ;
235 }
Portanto, o Tomcat 7 simplesmente não exibe nenhum aviso quando não consegue liberar o cache, enquanto o Tomcat 8 exibe um aviso.
Portanto, se você estiver usando o Tomcat 8 com a mesma configuração de cache padrão do Tomcat 7 e recebeu avisos no Tomcat 8, então suas (e minhas) configurações de cache do Tomcat 7 estavam funcionando mal sem aviso.
2.4 Soluções
Existem várias soluções:
- Aumentar o cache (recomendado)
- Diminua o TTL (não recomendado)
- Suprimir avisos de log de cache (não recomendado)
- Desativar cache
2.4.1. Aumentar o cache (recomendado)
Conforme descrito aqui: http://tomcat.apache.org/tomcat-8.0-doc/config/resources.html
Adicionando <Resources cacheMaxSize="XXXXX" />dentro do Contextelemento em $CATALINA_BASE/conf/context.xml, onde "XXXXX" representa um tamanho de cache aumentado, especificado em kbytes. O padrão é 10240 (10 mbyte), então defina um tamanho maior do que isso.
Você terá que ajustar para configurações ideais. Observe que o problema pode voltar quando, de repente, houver um aumento nas solicitações de tráfego / recursos.
Para evitar ter que reiniciar o servidor toda vez que você quiser tentar um novo tamanho de cache, você pode alterá-lo sem reiniciar usando JMX.
Para habilitar JMX , adicionar isso para $CATALINA_BASE/conf/server.xmldentro do Serverelemento:
<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="6767" rmiServerPortPlatform="6768" />e descarga catalina-jmx-remote.jarde https://tomcat.apache.org/download-80.cgi e colocá-lo em $CATALINA_HOME/lib. Em seguida, use o jConsole (fornecido por padrão com o Java JDK) para se conectar por JMX ao servidor e verifique as configurações para aumentar o tamanho do cache enquanto o servidor está em execução. As alterações nessas configurações devem entrar em vigor imediatamente.
2.4.2. Diminua o TTL (não recomendado)
Diminua o cacheTtlvalor em um valor inferior a 5000 milissegundos e ajuste para obter as configurações ideais.
Por exemplo: <Resources cacheTtl="2000" />
Isso se resume a ter e preencher um cache na memória RAM sem usá-lo.
2.4.3. Suprimir avisos de log de cache (não recomendado)
Configure o log para desabilitar o logger org.apache.catalina.webresources.Cache.
Para obter mais informações sobre como fazer login no Tomcat: http://tomcat.apache.org/tomcat-8.0-doc/logging.html
2.4.4. Desativar cache
Você pode desativar o cache configurando cachingAllowedpara false.
<Resources cachingAllowed="false" />
Embora eu possa me lembrar que em uma versão beta do Tomcat 8, eu estava usando JMX para desabilitar o cache. (Não sei exatamente por que, mas pode haver um problema com a desativação do cache via server.xml.)