Programing

Tomcat 8 던지기-org.apache.catalina.webresources.Cache.getResource 리소스를 추가 할 수 없습니다.

crosscheck 2020. 8. 11. 07:52
반응형

Tomcat 8 던지기-org.apache.catalina.webresources.Cache.getResource 리소스를 추가 할 수 없습니다.


방금 Tomcat을 버전 7.0.52에서 8.0.14로 업그레이드했습니다.

많은 정적 이미지 파일에 대해 이것을 얻고 있습니다.

org.apache.catalina.webresources.Cache.getResource 만료 된 캐시 항목을 제거한 후 사용 가능한 여유 공간이 부족하여 [/base/1325/WA6144-150x112.jpg]의 리소스를 캐시에 추가 할 수 없습니다. 최대 크기를 늘리는 것이 좋습니다. 캐시

특정 리소스 설정을 지정하지 않았으며 7.0.52에 대해이 설정을 얻지 못했습니다.

나는 이것이 수정되었다고 추정되는 버그 보고서에서 시작시 발생한다는 언급을 발견했습니다. 나에게 이것은 시작시가 아니라 리소스가 요청 될 때 지속적으로 발생합니다.

이 문제가있는 다른 사람이 있습니까?

적어도 캐시를 비활성화하려고 시도했지만 캐시를 사용하지 않도록 지정하는 방법의 예를 찾을 수 없습니다. 속성은 Tomcat 버전 8의 컨텍스트에서 사라졌습니다. 자원 추가를 시도했지만 구성 권한을 얻을 수 없습니다.

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

감사.


$CATALINA_BASE/conf/context.xml아래 추가 블록에서</Context>

<Resources cachingAllowed="true" cacheMaxSize="100000" />

자세한 정보 : http://tomcat.apache.org/tomcat-8.0-doc/config/resources.html


Tomcat 7에서 8로 업그레이드 할 때 동일한 문제가 발생했습니다. 캐시에 대한 로그 경고가 계속해서 많이 발생했습니다.

1. 짧은 답변

다음을 Contextxml 요소에 추가 하십시오 $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(10mbyte)이므로 이보다 큰 크기를 설정하십시오. 경고가 사라지는 최적의 설정을 위해 조정하십시오. 교통량이 많은 상황에서는 경고가 다시 표시 될 수 있습니다.

1.1 원인 (간단한 설명)

이 문제는 Tomcat이 해당 항목의 TTL보다 작은 캐시 항목으로 인해 대상 캐시 크기에 도달 할 수 없기 때문에 발생합니다. 따라서 Tomcat은 만료 될 수있는 충분한 캐시 항목이 없었습니다. 너무 신선했기 때문에 캐시를 충분히 확보 할 수 없어서 경고를 출력했습니다.

Tomcat 7은이 상황에서 경고를 출력하지 않았기 때문에 Tomcat 7에서는 문제가 나타나지 않았습니다. (귀하와 나에게 알리지 않고 잘못된 캐시 설정을 사용하게됩니다.)

이 문제는 캐시의 크기 및 TTL에 비해 상대적으로 짧은 시간 동안 리소스에 대한 상대적으로 많은 양의 HTTP 요청 (일반적으로 정적)을 수신 할 때 나타납니다. 캐시가 최대 크기 (기본적으로 10MB)에 도달하고 새 캐시 항목이있는 크기의 95 % 이상 (새로 고침은 캐시에서 5 초 미만을 의미 함)에 도달하면 Tomcat이 시도하는 각 webResource에 대한 경고 메시지가 표시됩니다. 캐시에로드합니다.

1.2 선택적 정보

재부팅하지 않고 실행중인 서버에서 cacheMaxSize를 조정해야하는 경우 JMX를 사용하십시오.

가장 빠른 해결 방법은 cache :를 완전히 비활성화하는 <Resources cachingAllowed="false" />것이지만 이는 차선책이므로 방금 설명한대로 cacheMaxSize를 늘리십시오.

2. 긴 답변

2.1 배경 정보

WebSource는 웹 응용 프로그램에서 파일이나 디렉토리입니다. 성능상의 이유로 Tomcat은 WebSource를 캐시 할 수 있습니다. 정적 리소스 캐시최대 값 (전체 리소스)은 기본적으로 10240KB (10MB)입니다. webResource가 요청 될 때 (예 : 정적 이미지를로드 할 때) 캐시 항목이라고 불리는 webResource가 캐시에로드됩니다. 모든 캐시 항목에는 캐시 항목이 캐시에 머무를 수있는 시간 인 TTL (Time to Live)이 있습니다. TTL이 만료되면 캐시 항목을 캐시에서 제거 할 수 있습니다. cacheTTL의 기본값은 5000 밀리 초 (5 초)입니다.

캐싱에 대해 더 많은 정보가 있지만 이는 문제와 관련이 없습니다.

2.2 원인

Cache 클래스 의 다음 코드 는 캐싱 정책을 자세히 보여줍니다.

152   // 콘텐츠는 캐시되지 않지만 메타 데이터 크기 
153 long delta = cacheEntry가 필요합니다. getSize ();
154 사이즈. addAndGet (델타);
156 if (size. get ()> maxSize) {
157 // 속도를 위해 정렬되지 않은 리소스를 처리합니다. 거래 캐시
(158) // 효율 (이하 항목 전에 이전 퇴거 될 수있다
(159 명) 이 대 임계 경로가 이후 속도 //들)
(160) 의 처리 요구 //
161 targetSize가 =
162 이 maxSize * (100 - TARGET_FREE_PERCENT_GET) / 100;
163 long newSize = evict (
164 targetSize, resourceCache. values (). iterator ());
165 if (newSize> maxSize) {
166 //이 리소스를위한 충분한 공간을 만들 수 없습니다.
167 // 캐시에서 제거합니다.
168 removeCacheEntry (path);
169 로그. 경고 (sm. getString ( "cache.addFail", 경로));
170 }
171 }

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 }

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

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.

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 }

combined with:

231  while (toFree > 0) {
232 if (attempts == maxAllocateIterations) {
233 // Give up, no changes are made to the current cache
234 return false;
235 }

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.

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.

2.4 Solutions

There are multiple solutions:

  1. Increase cache (recommended)
  2. Lower the TTL (not recommended)
  3. Suppress cache log warnings (not recommended)
  4. Disable cache

2.4.1. Increase cache (recommended)

As described here: http://tomcat.apache.org/tomcat-8.0-doc/config/resources.html

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.

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.

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.

2.4.2. Lower the TTL (not recommended)

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

For example: <Resources cacheMaxSize="2000" />

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

2.4.3. Suppress cache log warnings (not recommended)

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

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

2.4.4. Disable cache

You can disable the cache by setting cachingAllowed to false. <Resources cachingAllowed="false" />

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.)


You have more static resources that the cache has room for. You can do one of the following:

  • Increase the size of the cache
  • Decrease the TTL for the cache
  • Disable caching

For more details see the documentation for these configuration options.


In case it helps anyone else, the only way I was able to solve this problem was to append the following to conf/logging.properties:

org.apache.catalina.webresources.Cache.level = SEVERE

경고 수준에있는 "리소스를 추가 할 수 없음"로그가 필터링됩니다.

참고 URL : https://stackoverflow.com/questions/26893297/tomcat-8-throwing-org-apache-catalina-webresources-cache-getresource-unable-to

반응형