Caching Tomcat 8-org.apache.catalina.webresources.Cache.getResource无法添加资源

Caching Tomcat 8-org.apache.catalina.webresources.Cache.getResource无法添加资源,caching,resources,tomcat8,Caching,Resources,Tomcat8,我刚刚将Tomcat从7.0.52版升级到8.0.14版 我得到了很多静态图像文件: org.apache.catalina.webresources.Cache.getResource无法添加 将位于[/base/1325/WA6144-150x112.jpg]的资源添加到缓存中,因为存在 收回过期缓存后可用空间不足 条目-考虑增加缓存的最大大小 我没有指定任何特定的资源设置,我也没有在7.0.52中获得此设置 我在一份据说已经修复的bug报告中发现了在启动时发生的这种情况。对我来说,这不是在

我刚刚将Tomcat从7.0.52版升级到8.0.14版

我得到了很多静态图像文件:

org.apache.catalina.webresources.Cache.getResource无法添加 将位于[/base/1325/WA6144-150x112.jpg]的资源添加到缓存中,因为存在 收回过期缓存后可用空间不足 条目-考虑增加缓存的最大大小

我没有指定任何特定的资源设置,我也没有在7.0.52中获得此设置

我在一份据说已经修复的bug报告中发现了在启动时发生的这种情况。对我来说,这不是在启动时发生的,而是在请求资源时不断发生的

还有谁有这个问题吗

试图至少禁用缓存,但我找不到如何指定不使用缓存的示例。属性已经从Tomcat版本8的上下文中删除。已尝试添加资源,但无法正确配置



谢谢。

您有更多的静态资源,缓存可以容纳这些资源。您可以执行以下操作之一:

  • 增加缓存的大小
  • 降低缓存的TTL
  • 禁用缓存

有关这些配置选项的更多详细信息,请参阅。

我在从Tomcat 7升级到8时遇到了相同的问题:有关缓存的日志警告持续大量出现

1.简短回答 将其添加到
$CATALINA_BASE/conf/context.xml的xml元素中:


因此默认值为
10240
(10兆字节),因此设置一个大于此值的大小。然后在警告消失的地方进行优化设置。 请注意,在交通量较大的情况下,警告可能会再次出现

1.1原因(简要说明) 问题是由于Tomcat无法达到其目标缓存大小,因为缓存项小于这些项的TTL。所以Tomcat没有足够的缓存条目,它可能会过期,因为它们太新,所以它无法释放足够的缓存,从而输出警告

这个问题没有出现在Tomcat7中,因为Tomcat7在这种情况下根本没有输出警告。(导致您和我在未得到通知的情况下使用糟糕的缓存设置。)

与缓存的大小和TTL相比,在相对较短的时间内接收到相对大量的HTTP资源请求(通常是静态的)时,就会出现问题。如果缓存达到最大值(默认情况下为10mb),且其大小的95%以上都有新的缓存项(fresh意味着缓存中的时间少于5秒),那么对于Tomcat尝试加载到缓存中的每个webResource,您将收到一条警告消息

1.2可选信息 如果需要在运行的服务器上调优cacheMaxSize而不重新启动它,请使用JMX

最快的修复方法是完全禁用cache:
,但这是次优的,所以如我刚才所述增加cacheMaxSize

2.长话短说 2.1背景资料 是web应用程序中的文件或目录。出于性能原因,Tomcat可以缓存Web资源。默认情况下(所有资源总计)为10240 KB(10 MB)。当请求webResource时(例如加载静态图像时),webResource被加载到缓存中,然后称为缓存项。 每个缓存项都有一个(生存时间),即允许缓存项停留在缓存中的时间。当TTL过期时,缓存项有资格从缓存中删除。cacheTTL的默认值为5000毫秒(5秒)

关于缓存还有更多的内容要讲,但这与问题无关

2.2原因 中的以下代码详细显示了缓存策略:

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 }
2.3问题 正如警告信息所说,问题在于

删除过期缓存条目后可用空间不足-考虑增加缓存的最大大小< /P> 如果您的web应用程序在短时间(5秒)内加载了大量未缓存的web资源(大约最大缓存,默认为10mb),那么您将收到警告

令人困惑的是Tomcat7没有显示警告。这只是由以下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 }
//将新条目添加到缓存
已同步(缓存){
检查缓存大小,如果太大,则删除元素
如果((缓存。(名称)==null)和&cache。(entry.size)){
缓存。(条目);
}
}
}
结合:

231 while (toFree > 0) {
232 if (attempts == maxAllocateIterations) {
233 // Give up, no changes are made to the current cache
234 return false;
235 }
而(toFree>0){
如果(尝试==MaxAllocateInteractions){
放弃,则不会对当前缓存进行任何更改
返回false;
}
因此,当Tomcat7无法释放缓存时,它根本不输出任何警告,而Tomcat8将输出警告

因此,如果您使用与Tomcat 7相同的默认缓存配置的Tomcat 8,并且在Tomcat 8中收到警告,那么您(和我)的Tomcat 7缓存设置在没有警告的情况下表现不佳

2.4解决办法 有多种解决方案:

  • 增加缓存(推荐)
  • 降低TTL(不推荐)
  • 抑制缓存日志警告(不推荐)
  • 禁用缓存
  • 2.4.1.增加缓存(推荐) 如下所述:

    通过在
    $CATALINA_BASE/conf/Context.xml
    中的
    上下文
    元素中添加
    ,其中“XXXXX”表示增加的缓存大小,以KB为单位指定。默认值为10240(10 MB),因此设置一个大于此值的大小

    您必须调整最佳设置。请注意,当流量/资源请求突然增加时,问题可能会再次出现

    为了避免每次尝试新的缓存大小时都必须重新启动服务器,可以使用JMX在不重新启动的情况下对其进行更改

    若要删除,请将此添加到
    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
    
    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 }
    231 while (toFree > 0) {
    232 if (attempts == maxAllocateIterations) {
    233 // Give up, no changes are made to the current cache
    234 return false;
    235 }
    org.apache.catalina.webresources.Cache.level = SEVERE
    
    <Resources cachingAllowed="true" cacheMaxSize="100000" />