我刚刚将Tomcat从7.0.52版本升级到8.0.14。
我得到这个对于很多静态图像文件:
org.apache.catalina.webresources.Cache.getResource无法添加在[/base/1325/wa6144 - 1500x112 .jpg]的资源到缓存,因为那里清除过期缓存后可用空间不足条目-考虑增加缓存的最大大小
我没有指定任何特定的资源设置,我没有得到这个7.0.52。
我在一个应该被修复的bug报告中发现了这个在启动时发生的情况。对我来说,这不是在启动时发生的,而是在请求资源时不断发生的。
还有人有这个问题吗?
尝试至少只是禁用缓存,但我找不到一个如何指定不使用缓存的例子。在Tomcat版本8中,属性已经从上下文中消失了。尝试添加资源,但配置不正确。
<Resource name="file"
cachingAllowed="false"
className="org.apache.catalina.webresources.FileResourceSet"
/>
谢谢。
我在从Tomcat 7升级到Tomcat 8时遇到了同样的问题:关于缓存的连续大量日志警告。
<标题>1。简短的回答将此添加到$CATALINA_BASE/conf/context.xml
的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" />
所以默认值是10240
(10 mbyte),所以设置一个比这个大的大小。然后调优到警告消失的最佳设置。请注意,在流量较大的情况下,警告可能会再次出现。
1.1原因(简短说明)
这个问题是由于Tomcat无法达到其目标缓存大小,因为缓存条目小于这些条目的TTL。所以Tomcat没有足够的缓存条目可以过期,因为它们太新鲜了,所以它不能释放足够的缓存,因此输出警告。
这个问题在Tomcat 7中没有出现,因为Tomcat 7在这种情况下根本没有输出警告。(导致你和我在没有通知的情况下使用糟糕的缓存设置)
与缓存的大小和TTL相比,当在相对较短的时间内接收到相对大量的资源(通常是静态的)HTTP请求时,问题就会出现。如果缓存达到最大值(默认为10mb),并且95%以上的缓存条目是新鲜的(新鲜意味着在缓存中少于5秒),那么您将收到Tomcat试图在缓存中加载的每个webResource的警告消息。
1.2可选信息如果您需要在运行的服务器上调优cacheMaxSize而不需要重新启动它,请使用JMX。
最快的解决办法是完全禁用缓存:<Resources cachingAllowed="false" />
,但这不是最优的,所以像我刚才描述的那样增加cacheMaxSize。
WebSource是web应用程序中的一个文件或目录。出于性能考虑,Tomcat可以缓存websource。默认情况下,静态资源缓存(所有资源的总和)的最大值为10240kbyte (10mbyte)。当webResource被请求时(例如加载静态图像时),它被加载到缓存中,然后被称为缓存条目。每个缓存项都有一个TTL(生存时间),这是允许缓存项在缓存中停留的时间。当TTL过期时,缓存条目有资格从缓存中删除。cacheTTL的默认值是5000毫秒(5秒)。
还有更多关于缓存的内容,但这与问题无关。
2.2原因
来自Cache类的以下代码详细显示了缓存策略:
152//内容不会被缓存,但是我们仍然需要元数据大小
153longdelta = cacheEntry.getSize();
154 size. addandget (delta);
156if(size.get()>maxSize) {
157//为了提高速度,对资源进行无序处理。交换缓存
158//效率(较年轻的条目可能会在较老的
159//之前被清除)以提高速度,因为这是
160的关键路径//请求处理
161longtargetSize =
162 maxSize * (100 - TARGET_FREE_PERCENT_GET)/100;
163longnewSize = evict(
164 targetSize,
165if(newSize>maxSize) {
166//无法为该资源创建足够的空间
167//从缓存中删除
168 removeCacheEntry(path);
169 log.warn(smm . getstring ("cache. size ");
170}
171}
当加载webResource时,代码计算缓存的新大小。如果计算大小大于默认最大大小,则必须删除一个或多个缓存条目,否则新大小将超过最大值。因此,代码将计算一个"targetSize",这是缓存希望保持的大小(作为最佳值),默认情况下是最大值的95%。为了达到这个targetSize,必须从缓存中删除/驱逐条目。这是使用以下代码完成的:
215privatelongevict(longtargetSize, Iteratoriter) {
217longnow = System.currentTimeMillis();
219longnewSize = size.get();
221while(newSize>targetSize &&iter.hasNext()) {
222 CachedResource resource = iter.next();
224//不要过期任何在TTL内检查的
225if(resource. getnextcheck ()>now) {
226continue
227}
229//从缓存中删除条目
230 removeCacheEntry(resource. getwebapppath ());
232 newSize = size.get();
233}
235returnnewSize;
236}
所以缓存条目被删除时
TTL已过期,targetSize还未达到。在尝试通过清除缓存项来释放缓存后,代码将执行:
165if(newSize>maxSize) {
166//无法为该资源创建足够的空间
167//从缓存中删除
168 removeCacheEntry(path);
169 log.warn(smm . getstring ("cache. size ")
因此,如果在尝试释放缓存后,大小仍然超过最大值,它将显示无法释放的警告消息:
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问题如警告信息所示,问题出在
清除过期缓存项后可用空闲空间不足-考虑增加缓存的最大大小
如果你的web应用程序在短时间(5秒)内加载了大量未缓存的web资源(大约最大缓存,默认为10mb),那么你会收到警告。
令人困惑的部分是Tomcat 7没有显示警告。这是由Tomcat 7代码引起的:
1606//添加新条目到缓存
1607synchronized(cache) {
1608//检查缓存大小,如果太大则删除元素
1609if((cache.lookup(name) ==null) &&Cache.allocate (entry.size)) {
1610 cache.load(entry);
1611}
1612}
结合:
231while(toFree>0) {
232if(attempts == maxAllocateIterations) {
233//放弃,不改变当前缓存
234返回false;
235}
所以Tomcat 7在无法释放缓存时根本不输出任何警告,而Tomcat 8会输出一个警告
所以如果你使用Tomcat 8和Tomcat 7的默认缓存配置,并且你在Tomcat 8中收到警告,那么你的(和我的)Tomcat 7的缓存设置在没有警告的情况下表现很差。
2.4解决方案有多种解决方案:
- 增加缓存(推荐)
- 降低TTL值(不推荐)
- 禁止缓存日志警告(不推荐) <
- 禁用缓存/gh>
2.4.1。增加缓存(推荐)
如下所述:http://tomcat.apache.org/tomcat-8.0-doc/config/resources.html
通过在$CATALINA_BASE/conf/context.xml
的Context
元素中添加<Resources cacheMaxSize="XXXXX" />
,其中"XXXXX"表示增加的缓存大小,以kb指定。默认值是10240 (10mbyte),所以请设置一个比这个大的大小。
你必须调整到最佳设置。请注意,当流量/资源请求突然增加时,问题可能会再次出现。
为了避免每次尝试新的缓存大小时都必须重新启动服务器,可以使用JMX在不重新启动的情况下更改它。
要启用JMX,将此添加到Server
元素中的$CATALINA_BASE/conf/server.xml
中:<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="6767" rmiServerPortPlatform="6768" />
和从https://tomcat.apache.org/download-80.cgi下载catalina-jmx-remote.jar
,并把它放在$CATALINA_HOME/lib
。然后使用jConsole(默认情况下与Java JDK一起提供)通过JMX连接到服务器,并在服务器运行时查看设置以增加缓存大小。这些设置的更改应立即生效。
2.4.2。降低TTL(不推荐)
将cacheTtl
值降低到低于5000毫秒的值,并调整为最佳设置。
例如:<Resources cacheTtl="2000" />
这有效地归结为在ram中拥有和填充缓存而不使用它。
2.4.3。禁用缓存日志警告(不推荐)
配置日志以禁用org.apache.catalina.webresources.Cache
的日志记录器。
有关登录Tomcat的更多信息:http://tomcat.apache.org/tomcat-8.0-doc/logging.html
如果是2.4.4。禁用缓存
设置cachingAllowed
为false
可以禁用缓存。<Resources cachingAllowed="false" />
虽然我记得在Tomcat 8的测试版中,我使用JMX禁用缓存。(不确定具体原因,但通过server.xml禁用缓存可能会有问题。)
在您的$CATALINA_BASE/conf/context.xml
中添加</Context>
之前的块
<Resources cachingAllowed="true" cacheMaxSize="100000" />
更多信息:http://tomcat.apache.org/tomcat-8.0-doc/config/resources.html
您有更多的静态资源,缓存有足够的空间。您可以执行以下操作之一:
- 增加缓存的大小
- 减少缓存的TTL
- 禁用缓存gh>
有关这些配置选项的详细信息,请参阅文档。
这不是一个解决方案,因为它没有解决导致消息出现在日志中的条件,但是可以通过向conf/logging.properties
添加以下内容来抑制消息:
org.apache.catalina.webresources.Cache.level = SEVERE
过滤掉WARNING级别的"无法添加资源"日志。
在我看来,WARNING
不一定是需要解决的错误,如果需要,可以忽略。
更多提示(我遇到的问题):如果$CATALINA_BASE/conf/context.xml被intellij.
只需添加内部块<Context> </Context>
:
<Resources cachingAllowed="true" cacheMaxSize="100000" />
在您的Tomcat/apache-tomcat-x.x.x/conf/context.xml