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


111

방금 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"
/>  

감사.


답글 없음-이 문제가있는 사람은 나뿐 인 것 같습니다.
iainmac999 2014


1
Tomcat 8 컨텍스트에서 누락 된 속성과 관련하여 다음은 마이그레이션 가이드에서 발췌 한 것입니다 (강조 표시). " 리소스 리팩토링으로 인해 기본 컨텍스트 구현 (org.apache.catalina.core) 에서 여러 속성이 제거되었습니다. .StandardContext). 이제 다음 속성 웹 애플리케이션에서 사용 하는 리소스 구현을 통해 구성 할 수 있습니다 . 관련 마이그레이션 GUID 에 대한 자세한 정보 .
informatik01

@ iainmac999는 2 년이 지난 후에도 정답을 선택하지 않았는데 우리는 그것이 두 가지 방식으로 작동한다는 데 동의 할 수 있습니까?
davidjmcclelland

답변:



152

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 }

webResource를로드 할 때 코드는 캐시의 새 크기를 계산합니다. 계산 된 크기가 기본 최대 크기보다 크면 하나 이상의 캐시 된 항목을 제거해야합니다. 그렇지 않으면 새 크기가 최대 크기를 초과합니다. 따라서 코드는 "targetSize"를 계산합니다. 이는 캐시가 (최적 값으로) 유지하려는 크기이며 기본적으로 최대 값의 95 %입니다. 이 targetSize에 도달하려면 항목을 캐시에서 제거 / 제거해야합니다. 이것은 다음 코드를 사용하여 수행됩니다.

215   private  long evict ( long targetSize, Iterator < CachedResource > iter) { 
217 long now = 시스템. currentTimeMillis ();
219 long newSize = 크기. get ();
221 while (newSize> targetSize && iter. hasNext ()) {
222 CachedResource resource = iter. 다음 ();
224 // TTL 내에서 확인 된 항목을 만료하지 않음
225 if (resource. getNextCheck ()> now) {
226 계속 ;
227 }
229 // 캐시에서 항목 제거
230 removeCacheEntry (resource. getWebappPath ());
232 newSize = 크기. get ();
233 }
235 return newSize;
236 }

따라서 TTL이 만료되고 targetSize에 아직 도달하지 않은 경우 캐시 항목이 제거됩니다.

캐시 항목을 제거하여 캐시를 해제하려고 시도한 후 코드는 다음을 수행합니다.

165   if (newSize> maxSize) { 
166 //이 리소스에 대해 충분한 공간을 만들 수 없습니다.
167 // 캐시에서 제거합니다.
168 removeCacheEntry (path);
169 로그. 경고 (sm. getString ( "cache.addFail", 경로));
170 }

따라서 캐시를 해제하려는 시도 후에도 크기가 여전히 최대 값을 초과하면 해제 할 수 없다는 경고 메시지가 표시됩니다.

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

따라서 경고 메시지에서 알 수 있듯이 문제는

만료 된 캐시 항목을 제거한 후 사용 가능한 여유 공간이 부족합니다. 캐시의 최대 크기를 늘리는 것이 좋습니다.

웹 애플리케이션이 짧은 시간 (5 초) 내에 캐시되지 않은 많은 webResources (대략 최대 캐시, 기본적으로 10MB)를로드하면 경고가 표시됩니다.

혼란스러운 부분은 Tomcat 7이 경고를 표시하지 않았다는 것입니다. 이것은 단순히 다음 Tomcat 7 코드로 인해 발생합니다.

1606   // 캐시에 새 항목 추가 
1607 동기화 됨 (캐시) {
1608 // 캐시 크기를 확인하고 너무 크면 요소 제거
1609 if ((cache. lookup (name) == null ) && cache. allocate (entry.size) ) {
1610 캐시. 로드 (항목);
1611 }
1612 }

다음과 결합 :

231   while (toFree> 0) { 
232 if (attempts == maxAllocateIterations) {
233 // 포기, 현재 캐시가 변경되지 않음
234 return false ;
235 }

따라서 Tomcat 7은 캐시를 해제 할 수 없을 때 경고를 전혀 출력하지 않는 반면 Tomcat 8은 경고를 출력합니다.

따라서 Tomcat 7과 동일한 기본 캐싱 구성으로 Tomcat 8을 사용하고 Tomcat 8에서 경고가 표시되면 Tomcat 7의 캐싱 설정이 경고없이 제대로 수행되지 않은 것입니다.

2.4 솔루션

여러 솔루션이 있습니다.

  1. 캐시 늘리기 (권장)
  2. TTL 낮추기 (권장하지 않음)
  3. 캐시 로그 경고 표시 안 함 (권장하지 않음)
  4. 캐시 비활성화

2.4.1. 캐시 늘리기 (권장)

여기에 설명 된대로 : http://tomcat.apache.org/tomcat-8.0-doc/config/resources.html

<Resources cacheMaxSize="XXXXX" />Context요소 내에 추가 합니다 $CATALINA_BASE/conf/context.xml. 여기서 "XXXXX"는 증가 된 캐시 크기를 나타내며 KB 단위로 지정됩니다. 기본값은 10240 (10mbyte)이므로 이보다 큰 크기를 설정하십시오.

최적의 설정을 위해 조정해야합니다. 트래픽 / 리소스 요청이 갑자기 증가하면 문제가 다시 발생할 수 있습니다.

새 캐시 크기를 시도 할 때마다 서버를 다시 시작할 필요가 없도록 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를 통해 서버에 연결하고 설정을 살펴보고 서버가 실행되는 동안 캐시 크기를 늘립니다. 이러한 설정의 변경 사항은 즉시 적용됩니다.

2.4.2. TTL 낮추기 (권장하지 않음)

낮은 cacheTtl최적의 설정에 대한 낮은 5000 밀리 초보다 뭔가에 의해 값과 조정.

예를 들면 : <Resources cacheTtl="2000" />

이것은 효과적으로 캐시를 사용하지 않고 램에 캐시를 채우는 것으로 귀결됩니다.

2.4.3. 캐시 로그 경고 표시 안 함 (권장하지 않음)

에 대한 로거를 비활성화하도록 로깅을 구성합니다 org.apache.catalina.webresources.Cache.

Tomcat 로그인에 대한 자세한 정보 : http://tomcat.apache.org/tomcat-8.0-doc/logging.html

2.4.4. 캐시 비활성화

당신은 설정하여 캐시를 비활성화 할 수 있습니다 cachingAllowedfalse. <Resources cachingAllowed="false" />

Tomcat 8의 베타 버전에서는 JMX를 사용하여 캐시를 비활성화 한 것을 기억할 수 있습니다. (정확한 이유는 모르지만 server.xml을 통해 캐시를 비활성화하는 데 문제가있을 수 있습니다.)


캐시를 늘리시겠습니까? 나는 그것이 작동 할 것 같지 않다 ... 나는 이것을 보았다 : private long maxSize = 10 * 1024 * 1024; 소스에서. grepcode.com/file/repo1.maven.org/maven2/org.apache.tomcat/…
HoaPhan

당신은 왜 tomcat8가 침수되는 캐시 warnnings에 대한 답을 발견했다
PHP 어벤져

@HoaPhan 10 * 1024 * 1024는 전체 캐시에 대해 최대 10MB입니다. 웹앱의 트래픽에 따라 몇 초 내에 도달 할 수 있습니다. 충분히 늘리면 효과가 있습니다.
Devabc

@PHPAvenger Tomcat 7은이 자리에서 전혀 경고하지 않았지만 Tomcat 8은 경고 기능으로 볼 수 있습니다. 문제는 한 번뿐 아니라 모든 to-cache 리소스 요청에 대해 경고한다는 것입니다. 일정 시간 또는 캐시 대상이 적중 된 후에 만 ​​경고하는 것이 개선 될 것입니다.
Devabc

@Devabc 완벽한 대답! SO 클래식!
gaurav

9

캐시에 공간이있는 더 많은 정적 리소스가 있습니다. 다음 중 하나를 수행 할 수 있습니다.

  • 캐시 크기 늘리기
  • 캐시에 대한 TTL을 줄입니다.
  • 캐싱 비활성화

자세한 내용은 이러한 구성 옵션에 대한 설명서 를 참조하십시오 .


1
댓글 주셔서 감사합니다. 나는 예외의 의미를 이해하고, 당신이 링크 한 문서를 읽었지만, 구성 변경없이 이것이 7에서 8로 변경되는 이유를 이해할 수 없습니다. 즉, 기본 파일 시스템 리소스 처리기가 변경 사항에 대한 참조없이 8-7에서 다른 이유이며 시작 버그가보고되어 수정 된 것으로 의심됩니다.
iainmac999 2014

1
아마도 마이그레이션 가이드 (특히 tomcat.apache.org/migration-8.html#Web_application_resources)를 읽었다면 상황이 더 명확 할 것입니다.
Mark Thomas

문서가 a)이 캐시에 들어가는 리소스와 이유 (많은 오해가 많습니다!)를 설명하고 b) 다른 설정이 가질 수있는 영향 (예 : 맹목적으로 각 웹앱의 캐시 설정을 만드는 것)을 설명하면 도움이 될 것입니다. 꽤 큰 것은 엄청난 양의 메모리를 먹을 수 있습니다.) 또한 응용 프로그램 자체에서 사용하는 정적 리소스 캐싱과 사용자 에이전트에서 요청하고 응용 프로그램에서 단순히 전달하는 정적 파일 사이에 코드 및 구성에 차이가있는 경우에도 도움이됩니다.
volkerk

4

이것은 메시지가 로그에 나타나는 조건을 해결하지 않는다는 점에서 해결책이 아니지만 다음을 추가하여 메시지를 억제 할 수 있습니다 conf/logging.properties.

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

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

내가보기에 a WARNING는 반드시 해결해야하는 오류는 아니지만 원하는 경우 무시할 수 있습니다.


8
ㅋ. 이것은 문제를 해결하지 못합니다. 그것은 그것을 보여주지 않습니다. WTF!
T3rm1

이는 그 자체로 심각한 문제가 될 수있는 과도한 로깅 문제를 해결합니다. 이전 바람둥이 버전의 동작으로 돌아가서 많은 사람들이 충분히 잘 작동 했으므로 그런 의미에서 문제를 "해결"합니다. 실제로 tomcat 캐시를 조정하는 문제는 다루지 않습니다. devabc의 답변은 매우 훌륭하게 다루고 있습니다.
volkerk
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.