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

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

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

org.apache.catalina.webresources.Cache.getResource 만료 된 캐시 항목을 제거한 후 사용 가능한 여유 공간이 부족하여 [/base/1325/WA6144-150×112.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 }

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을 통해 캐시를 비활성화하는 데 문제가있을 수 있습니다.)


답변

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

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

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


답변

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

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

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

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


답변