Tomcat 8 抛出 - org.apache.catalina.webresources.Cache.getResource 无法添加资源 [英] Tomcat 8 throwing - org.apache.catalina.webresources.Cache.getResource Unable to add the resource

查看:56
本文介绍了Tomcat 8 抛出 - org.apache.catalina.webresources.Cache.getResource 无法添加资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have just upgraded Tomcat from version 7.0.52 to 8.0.14.

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

I am getting this for lots of static image files:

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

org.apache.catalina.webresources.Cache.getResource Unable to add the resource at [/base/1325/WA6144-150x112.jpg] to the cache because there was insufficient free space available after evicting expired cache entries - consider increasing the maximum size of the cache

我没有指定任何特定的资源设置,而且我在 7.0.52 中没有得到这个.

I haven't specified any particular resource settings, and I didn't get this for 7.0.52.

我发现在一个据称已修复的错误报告中提到了启动时发生的这种情况.对我来说,这不是在启动时发生,而是在请求资源时不断发生.

I have found mention of this happening at startup in a bug report that was supposedly fixed. For me this is happening not at startup but constantly when the resource is requested.

还有其他人遇到这个问题吗?

Anybody else having this issue?

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

Trying to at least just disable the cache, but I cannot find an example of how to specify not to use the cache. The attributes have gone from the context in Tomcat version 8. Have tried adding a resource but cannot get the config right.

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

谢谢.

推荐答案

我在从 Tomcat 7 升级到 8 时遇到了同样的问题:关于缓存的大量日志警告不断涌现.

I had the same issue when upgrading from Tomcat 7 to 8: a continuous large flood of log warnings about cache.

Context 中添加 $CATALINA_BASE/conf/context.xml 的 xml 元素:

Add this within the Context xml element of your $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" />

所以默认值为 10240(10 兆字节),所以设置一个大于这个的大小.比调整警告消失的最佳设置.请注意,警告可能会在流量较大的情况下再次出现.

So the default is 10240 (10 mbyte), so set a size higher than this. Than tune for optimum settings where the warnings disappear. Note that the warnings may come back under higher traffic situations.

该问题是由于缓存条目小于这些条目的 TTL 导致 Tomcat 无法达到其目标缓存大小引起的.所以Tomcat没有足够的缓存条目可以过期,因为它们太新鲜了,所以它不能释放足够的缓存,从而输出警告.

The problem is caused by Tomcat being unable to reach its target cache size due to cache entries that are less than the TTL of those entries. So Tomcat didn't have enough cache entries that it could expire, because they were too fresh, so it couldn't free enough cache and thus outputs warnings.

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

The problem didn't appear in Tomcat 7 because Tomcat 7 simply didn't output warnings in this situation. (Causing you and me to use poor cache settings without being notified.)

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

The problem appears when receiving a relative large amount of HTTP requests for resources (usually static) in a relative short time period compared to the size and TTL of the cache. If the cache is reaching its maximum (10mb by default) with more than 95% of its size with fresh cache entries (fresh means less than less than 5 seconds in cache), than you will get a warning message for each webResource that Tomcat tries to load in the cache.

如果您需要在不重新启动的情况下在正在运行的服务器上调整 cacheMaxSize,请使用 JMX.

Use JMX if you need to tune cacheMaxSize on a running server without rebooting it.

最快的解决方法是完全禁用缓存:<Resources cachingAllowed="false"/>,但这是次优的,所以像我刚才描述的那样增加 cacheMaxSize.

The quickest fix would be to completely disable cache: <Resources cachingAllowed="false" />, but that's suboptimal, so increase cacheMaxSize as I just described.

A WebSource 是 Web 应用程序中的文件或目录.出于性能原因,Tomcat 可以缓存 WebSources.最大静态资源缓存(所有资源在总计)默认为 10240 KB(10 兆字节).当 webResource 被请求时(例如加载静态图像时),webResource 被加载到缓存中,然后它被称为缓存条目.每个缓存条目都有一个 TTL(生存时间),这是允许缓存条目留在缓存中的时间.当 TTL 到期时,缓存条目有资格从缓存中删除.cacheTTL 的默认值为 5000 毫秒(5 秒).

A WebSource is a file or directory in a web application. For performance reasons, Tomcat can cache WebSources. The maximum of the static resource cache (all resources in total) is by default 10240 kbyte (10 mbyte). A webResource is loaded into the cache when the webResource is requested (for example when loading a static image), it's then called a cache entry. Every cache entry has a TTL (time to live), which is the time that the cache entry is allowed to stay in the cache. When the TTL expires, the cache entry is eligible to be removed from the cache. The default value of the cacheTTL is 5000 milliseconds (5 seconds).

关于缓存还有很多要说的,但这与问题无关.

There is more to tell about caching, but that is irrelevant for the problem.

以下代码来自Cache class 详细展示了缓存策略:

The following code from the Cache class shows the caching policy in detail:

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 }

加载 webResource 时,代码会计算缓存的新大小.如果计算出的大小大于默认的最大大小,则必须删除一个或多个缓存条目,否则新大小将超过最大值.因此,代码将计算targetSize",这是缓存想要保持的大小(作为最佳值),默认情况下是最大值的 95%.为了达到这个目标大小,必须从缓存中删除/驱逐条目.这是使用以下代码完成的:

When loading a webResource, the code calculates the new size of the cache. If the calculated size is larger than the default maximum size, than one or more cached entries have to be removed, otherwise the new size will exceed the maximum. So the code will calculate a "targetSize", which is the size the cache wants to stay under (as an optimum), which is by default 95% of the maximum. In order to reach this targetSize, entries have to be removed/evicted from the cache. This is done using the following code:

215  private long evict(long targetSize, Iterator<CachedResource> iter) {
217 long now = System.currentTimeMillis();
219 long newSize = size.get();
221 while (newSize > targetSize && iter.hasNext()) {
222 CachedResource resource = iter.next();
224 // Don't expire anything that has been checked within the TTL
225 if (resource.getNextCheck() > now) {
226 continue;
227 }
229 // Remove the entry from the cache
230 removeCacheEntry(resource.getWebappPath());
232 newSize = size.get();
233 }
235 return newSize;
236 }

因此,当缓存条目的 TTL 到期且尚未达到 targetSize 时,它​​会被删除.

So a cache entry is removed when its TTL is expired and the targetSize hasn't been reached yet.

在尝试通过驱逐缓存条目来释放缓存后,代码将执行:

After the attempt to free cache by evicting cache entries, the code will do:

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 }

所以如果尝试释放缓存后,大小仍然超过最大值,则会显示无法释放的警告信息:

So if after the attempt to free cache, the size still exceeds the maximum, it will show the warning message about being unable to free:

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 问题

所以正如警告信息所说,问题是

2.3 The problem

So as the warning message says, the problem is

驱逐过期缓存条目后可用空间不足 - 考虑增加缓存的最大大小

insufficient free space available after evicting expired cache entries - consider increasing the maximum size of the cache

如果您的 Web 应用程序在短时间内(5 秒)内加载了大量未缓存的 webResources(大约最大缓存,默认为 10mb),那么您将收到警告.

If your web application loads a lot of uncached webResources (about maximum of cache, by default 10mb) within a short time (5 seconds), then you'll get the warning.

令人困惑的部分是 Tomcat 7 没有显示警告.这只是由这个 Tomcat 7 代码引起的:

The confusing part is that Tomcat 7 didn't show the warning. This is simply caused by this Tomcat 7 code:

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 }

因此,Tomcat 7 在无法释放缓存时根本不会输出任何警告,而 Tomcat 8 会输出警告.

So Tomcat 7 simply doesn't output any warning at all when it's unable to free cache, whereas Tomcat 8 will output a warning.

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

So if you are using Tomcat 8 with the same default caching configuration as Tomcat 7, and you got warnings in Tomcat 8, than your (and mine) caching settings of Tomcat 7 were performing poorly without warning.

有多种解决方案:

  1. 增加缓存(推荐)
  2. 降低 TTL(不推荐)
  3. 禁止缓存日志警告(不推荐)
  4. 禁用缓存

2.4.1.增加缓存(推荐)

如此处所述:http://tomcat.apache.org/tomcat-8.0-doc/config/resources.html

通过在 $CATALINA_BASE/conf/context.xmlContext 元素中添加 ,其中XXXXX"代表增加的缓存大小,以千字节为单位.默认为 10240(10 兆字节),因此请设置一个高于此值的大小.

By adding <Resources cacheMaxSize="XXXXX" /> within the Context element in $CATALINA_BASE/conf/context.xml, where "XXXXX" stands for an increased cache size, specified in kbytes. The default is 10240 (10 mbyte), so set a size higher than this.

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

You'll have to tune for optimum settings. Note that the problem may come back when you suddenly have an increase in traffic/resource requests.

为了避免每次想要尝试新的缓存大小时都必须重新启动服务器,您可以使用 JMX 更改它而无需重新启动.

To avoid having to restart the server every time you want to try a new cache size, you can change it without restarting by using JMX.

启用JMX,将其添加到 $CATALINA_BASE/conf/server.xmlServer 元素中:<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="6767" rmiServerPortPlatform="6768"/> 并下载catalina-jmx-remote.jar 来自 https://tomcat.apache.org/download-80.cgi 和把它放在 $CATALINA_HOME/lib 中.然后使用 jConsole(默认与 Java JDK 一起提供)通过 JMX 连接到服务器,并查看设置以在服务器运行时增加缓存大小.这些设置中的更改应立即生效.

To enable JMX, add this to $CATALINA_BASE/conf/server.xml within the Server element: <Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="6767" rmiServerPortPlatform="6768" /> and download catalina-jmx-remote.jar from https://tomcat.apache.org/download-80.cgi and put it in $CATALINA_HOME/lib. Then use jConsole (shipped by default with the Java JDK) to connect over JMX to the server and look through the settings for settings to increase the cache size while the server is running. Changes in these settings should take affect immediately.

cacheTtl 值降低低于 5000 毫秒的值并调整以获得最佳设置.

Lower the cacheTtl value by something lower than 5000 milliseconds and tune for optimal settings.

例如:

这实际上归结为在 ram 中拥有和填充缓存而不使用它.

This comes effectively down to having and filling a cache in ram without using it.

配置日志记录以禁用 org.apache.catalina.webresources.Cache 的记录器.

Configure logging to disable the logger for org.apache.catalina.webresources.Cache.

有关登录 Tomcat 的更多信息:http://tomcat.apache.org/tomcat-8.0-doc/logging.html

For more info about logging in Tomcat: http://tomcat.apache.org/tomcat-8.0-doc/logging.html

您可以通过设置cachingAllowedfalse.

虽然我记得在 Tomcat 8 的测试版中,我使用 JMX 来禁用缓存.(不知道究竟是为什么,但通过 server.xml 禁用缓存可能会出现问题.)

Although I can remember that in a beta version of Tomcat 8, I was using JMX to disable the cache. (Not sure why exactly, but there may be a problem with disabling the cache via server.xml.)

这篇关于Tomcat 8 抛出 - org.apache.catalina.webresources.Cache.getResource 无法添加资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆