Tomcat 8 fırlatma - org.apache.catalina.webresources.Cache.getResource Kaynak eklenemiyor


111

Tomcat'i 7.0.52'den 8.0.14'e yükselttim.

Bunu birçok statik resim dosyası için alıyorum:

org.apache.catalina.webresources.Cache.getResource [/base/1325/WA6144-150x112.jpg] adresindeki kaynak önbelleğe eklenemiyor çünkü süresi dolmuş önbellek girişlerini çıkardıktan sonra kullanılabilir boş alan yetersiz - maksimum boyutu artırmayı düşünün önbelleğin

Belirli bir kaynak ayarı belirtmedim ve bunu 7.0.52 için almadım.

Bunun başlangıçta olduğu söylenen bir hata raporunda sözde düzeltildiğini buldum. Benim için bu başlangıçta değil, kaynak talep edildiğinde sürekli oluyor.

Bu sorunu yaşayan başka biri var mı?

En azından önbelleği devre dışı bırakmaya çalışıyorum, ancak önbelleği kullanmamayı nasıl belirleyeceğime dair bir örnek bulamıyorum. Öznitelikler, Tomcat sürüm 8'deki bağlamdan çıkmıştır. Bir kaynak eklemeyi denediniz, ancak yapılandırmayı doğru yapamıyorsunuz.

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

Teşekkürler.


Cevap yok - sanırım bu sorunu yaşayan tek kişi ben olmalıyım.
iainmac999


1
Tomcat 8 bağlamındaki eksik öznitelikle ilgili olarak, burada geçiş kılavuzundan bir alıntı var (vurgu benim): " Kaynakların yeniden düzenlenmesi , varsayılan Bağlam uygulamasından (org.apache.catalina.core) bazı özniteliklerin kaldırılmasına da neden oldu .StandardContext). Aşağıdaki öznitelikler artık web uygulaması tarafından kullanılan kaynak uygulaması yoluyla yapılandırılabilir ". İlgili geçiş kılavuzunda daha fazla bilgi .
informatik01

@ iainmac999 2 yıl sonra hiçbir zaman doğru bir cevap seçmemiş olsaydık, her iki yönde de çalıştığını kabul edebilir miyiz?
davidjmcclelland

Yanıtlar:


161

Sizin de $CATALINA_BASE/conf/context.xmlönce aşağıdaki eklenti bloğu</Context>

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

Daha fazla bilgi için: http://tomcat.apache.org/tomcat-8.0-doc/config/resources.html


11
Bireysel okuyucular muhtemelen bu cacheMaxSize değerini 100 megabayttan daha düşük bir değere ayarlamak isteyeceklerdir.
Eric Spiegelberg

Şu ana kadar hata mesajı konsol günlüklerimi dolduruyordu. Şimdi temiz. Teşekkürler
Abubacker Siddik

152

Tomcat 7'den 8'e yükseltirken aynı sorunu yaşadım: önbellekle ilgili sürekli büyük günlük uyarıları.

1. Kısa Cevap

Bunu Contextxml öğenizin içine ekleyin $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" />

Yani varsayılan 10240(10 mbyte) 'dır, bu nedenle bundan daha büyük bir boyut ayarlayın. Daha sonra uyarıların kaybolduğu optimum ayarları ayarlayın. Uyarıların yüksek trafik koşullarında geri gelebileceğini unutmayın.

1.1 Nedeni (kısa açıklama)

Sorun, Tomcat'in bu girişlerin TTL'sinden daha düşük önbellek girişleri nedeniyle hedef önbellek boyutuna ulaşamamasından kaynaklanıyor. Yani Tomcat'in süresi dolabilecek kadar önbellek girişi yoktu, çünkü bunlar çok yeniydi, bu yüzden yeterince önbellek boşaltamadı ve bu nedenle uyarılar çıktı.

Sorun Tomcat 7'de görünmedi çünkü Tomcat 7 bu durumda uyarı vermedi. (Size ve bana bildirilmeden önbellek ayarlarını kötü kullanmamıza neden oluyor.)

Önbelleğin boyutuna ve TTL'sine kıyasla görece kısa bir süre içinde kaynaklar için görece büyük miktarda HTTP isteği (genellikle statik) alırken sorun ortaya çıkar. Önbellek, boyutunun% 95'inden fazlasını yeni önbellek girişleriyle (önbellekte 5 saniyeden az anlamına gelir) maksimum değerine (varsayılan olarak 10mb) ulaşıyorsa, Tomcat'in denediği her webResource için bir uyarı mesajı alacaksınız önbelleğe yüklemek için.

1.2 İsteğe bağlı bilgiler

Çalışan bir sunucuda cacheMaxSize'ı yeniden başlatmadan ayarlamanız gerekiyorsa JMX'i kullanın.

En hızlı çözüm <Resources cachingAllowed="false" />, önbelleği tamamen devre dışı bırakmak olacaktır: ancak bu yetersiz, bu nedenle az önce açıkladığım gibi cacheMaxSize değerini artırın.

2. Uzun Cevap

2.1 Arka plan bilgisi

Web Kaynağı , bir web uygulamasındaki bir dosya veya dizindir. Performans nedenleriyle Tomcat, Web Kaynaklarını önbelleğe alabilir. Statik kaynak önbelleği maksimum (toplamda bütün kaynaklar) varsayılan 10240 kbyte (10 Mbyte) gereğidir. WebResource istendiğinde (örneğin, statik bir görüntü yüklerken) önbelleğe bir webResource yüklenir ve buna önbellek girişi denir. Her önbellek girişinin bir TTL'si (yaşam süresi) vardır ve bu, önbellek girişinin önbellekte kalmasına izin verilen zamandır. TTL'nin süresi dolduğunda, önbellek girişi önbellekten kaldırılmaya uygun hale gelir. CacheTTL'nin varsayılan değeri 5000 milisaniyedir (5 saniye).

Önbelleğe alma hakkında söylenecek daha çok şey var, ancak bu sorunla ilgili değil.

2.2 Nedeni

Cache sınıfından alınan aşağıdaki kod , önbelleğe alma politikasını ayrıntılı olarak gösterir:

152   // İçerik önbelleğe alınmayacak, ancak yine de meta veri boyutuna ihtiyacımız var 
153 uzun delta = cacheEntry. getSize ();
154 beden. addAndGet (delta);
156 ise (boyut. Get ()> maxSize) {
157 // Süreç kaynakları hız için sırasız. İşlem önbelleği
158 // verimlilik (daha genç girdiler daha eski
159 olanlardan // önce çıkarılabilir ) çünkü bu,
160 için kritik yolda olduğundan // istek işleme
161 uzun targetSize =
162 maxSize * (100 - TARGET_FREE_PERCENT_GET) / 100;
163 uzun newSize = evict (
164 . TargetSize, ResourceCache değerleri (). Yineleyici ());
165 if (newSize> maxSize) {
166 // Bu kaynak için yeterli alan oluşturulamıyor
167 // Önbellekten kaldır
168 removeCacheEntry (yol);
169 günlük. warn (sm. getString ("cache.addFail", yol));
170 }
171 }

Bir webResource yüklenirken, kod önbelleğin yeni boyutunu hesaplar. Hesaplanan boyut varsayılan maksimum boyuttan büyükse, önbelleğe alınmış birden fazla girişin kaldırılması gerekir, aksi takdirde yeni boyut maksimum boyutu aşacaktır. Bu nedenle kod, önbelleğin altında kalmak istediği boyut olan (optimum olarak), varsayılan olarak maksimumun% 95'i olan bir "targetSize" hesaplayacaktır. Bu targetSize'ye ulaşmak için, girişlerin önbellekten kaldırılması / çıkarılması gerekir. Bu, aşağıdaki kod kullanılarak yapılır:

215   özel  uzun evict ( uzun targetSize, Iterator < CachedResource > iter) { 
217 long now = System. currentTimeMillis ();
219 uzun newSize = boyut. get ();
221 while (newSize> targetSize && iter. HasNext ()) {
222 CachedResource resource = iter. sonraki ();
224 // Do TTL içinde kontrol edildikten şey süresi dolmaz
225 ise (kaynak. GetNextCheck ()> şimdi) {
226 devam et ;
227 }
229 // Girdiyi önbellekten kaldır
230 removeCacheEntry (resource. GetWebappPath ());
232 newSize = boyut. get ();
233 }
235 dönüş newSize;
236 }

Dolayısıyla, TTL'sinin süresi dolduğunda ve targetSize henüz ulaşılmadığında bir önbellek girişi kaldırılır.

Önbellek girişlerini kaldırarak önbelleği boşaltma girişiminden sonra, kod şunları yapacaktır:

165   if (newSize> maxSize) { 
166 // Bu kaynak için yeterli alan oluşturulamıyor
167 // Önbellekten kaldır
168 removeCacheEntry (yol);
169 günlük. warn (sm. getString ("cache.addFail", yol));
170 }

Bu nedenle, önbelleği boşaltma girişiminden sonra, boyut yine de maksimum değeri aşarsa, serbest bırakılamama konusunda uyarı mesajı gösterecektir:

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 Sorun

Yani uyarı mesajının dediği gibi, sorun

süresi dolan önbellek girişlerini çıkardıktan sonra kullanılabilir boş alan yetersiz - önbelleğin maksimum boyutunu artırmayı düşünün

Web uygulamanız kısa bir süre (5 saniye) içinde çok sayıda önbelleğe alınmamış webResources (varsayılan olarak maksimum önbellek yaklaşık 10mb) yüklerse, uyarıyı alırsınız.

Kafa karıştıran kısım, Tomcat 7'nin uyarıyı göstermemesidir. Bunun nedeni basitçe bu Tomcat 7 kodudur:

1606   önbelleğe yeni bir girdi ekleyin // 
1607 senkronize (cache) {
1608 çok büyük olursa // Kontrol önbellek boyutu ve kaldır elemanları
1609 ise ((önbelleği. Araması (isim) == boş ) && önbellek. Ayrılamadı (entry.size) ) {
1610 önbellek. yük (giriş);
1611 }
1612 }

ile kombine:

231   iken (mesleğini serbestçe> 0) { 
232 ise (girişimlerini == maxAllocateIterations) {
233 // Vazgeç hiçbir değişiklik geçerli önbelleğe yapılan
234 dönüş FALSE ;
235 }

Bu yüzden Tomcat 7, önbelleği boşaltamadığında herhangi bir uyarı vermezken Tomcat 8 bir uyarı verir.

Dolayısıyla, Tomcat 8'i Tomcat 7 ile aynı varsayılan önbelleğe alma yapılandırmasıyla kullanıyorsanız ve Tomcat 8'de Tomcat 7'nin (ve benim) önbelleğe alma ayarlarınızın uyarı olmadan kötü performans gösterdiğinden farklı uyarılar aldıysanız.

2.4 Çözümler

Birden çok çözüm var:

  1. Önbelleği artır (önerilir)
  2. TTL'yi düşürün (önerilmez)
  3. Önbellek günlüğü uyarılarını bastır (önerilmez)
  4. Önbelleği devre dışı bırakın

2.4.1. Önbelleği artır (önerilir)

Burada açıklandığı gibi: http://tomcat.apache.org/tomcat-8.0-doc/config/resources.html

"XXXXX", kbayt cinsinden belirtilen artırılmış önbellek boyutunu ifade ettiği, <Resources cacheMaxSize="XXXXX" />içindeki Contextöğenin içine eklenerek $CATALINA_BASE/conf/context.xml. Varsayılan değer 10240'tır (10 mbyte), bu nedenle bundan daha büyük bir boyut ayarlayın.

Optimum ayarlar için ayarlamanız gerekecek. Trafik / kaynak isteklerinde aniden bir artış olduğunda sorunun geri gelebileceğini unutmayın.

Her yeni önbellek boyutunu denemek istediğinizde sunucuyu yeniden başlatmak zorunda kalmamak için, JMX kullanarak yeniden başlatmadan değiştirebilirsiniz.

İçin JMX etkinleştirmek için bu eklemek $CATALINA_BASE/conf/server.xmliçinde Servereleman: <Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="6767" rmiServerPortPlatform="6768" />ve indirme catalina-jmx-remote.jardan https://tomcat.apache.org/download-80.cgi ve koyun $CATALINA_HOME/lib. Ardından sunucuya JMX üzerinden bağlanmak için jConsole'u (varsayılan olarak Java JDK ile birlikte gelir) kullanın ve sunucu çalışırken önbellek boyutunu artırmak için ayarlara bakın. Bu ayarlarda yapılan değişiklikler hemen yürürlüğe girmelidir.

2.4.2. TTL'yi düşürün (önerilmez)

Alt cacheTtloptimum ayarları için düşük 5000 milisaniye daha bir şey tarafından değer ve ayar.

Örneğin: <Resources cacheTtl="2000" />

Bu, kullanmadan ram içinde bir önbelleğe sahip olmak ve onu doldurmak için etkili bir şekilde gelir.

2.4.3. Önbellek günlüğü uyarılarını bastır (önerilmez)

Günlükçüyü devre dışı bırakmak için günlük kaydını yapılandırın org.apache.catalina.webresources.Cache.

Tomcat'te oturum açma hakkında daha fazla bilgi için: http://tomcat.apache.org/tomcat-8.0-doc/logging.html

2.4.4. Önbelleği devre dışı bırakın

Sen ayarlayarak önbelleği devre dışı bırakabilir cachingAllowediçinfalse . <Resources cachingAllowed="false" />

Tomcat 8'in beta sürümünde bunu hatırlayabilsem de, önbelleği devre dışı bırakmak için JMX kullanıyordum. (Tam olarak neden olduğundan emin değilim, ancak önbelleğin server.xml aracılığıyla devre dışı bırakılmasıyla ilgili bir sorun olabilir.)


Önbellek artırılsın mı? İşe yarayacağından şüpheliyim ... Bunu gördüm: özel uzun maxSize = 10 * 1024 * 1024; kaynakta. grepcode.com/file/repo1.maven.org/maven2/org.apache.tomcat/…
HoaPhan

tomcat8'in neden önbellek uyarılarını doldurduğunun cevabını buldunuz mu
PHP Avenger

@ HoaPhan 10 * 1024 * 1024, toplamda tüm önbellek için maksimum 10mb'dir. Web uygulamasının trafiğine bağlı olarak buna saniyeler içinde ulaşılabilir. Yeterince arttırmak işe yarayacak.
Devabc

@PHPAvenger Tomcat 7 bu durumda hiç uyarmadı, oysa Tomcat 8 uyarıyor, bu yüzden bir uyarı özelliği olarak görülebilir. Sorun, yalnızca bir kez değil, her önbelleğe alınacak kaynak isteğinde uyarı vermesidir. Yalnızca belirli bir süre veya önbellek hedefi isabetlerinden sonra uyarmak bir gelişme olacaktır.
Devabc

@Devabc kusursuz cevap! ÇOK klasik!
gaurav

9

Önbelleğin yer aldığı daha fazla statik kaynağa sahipsiniz. Aşağıdakilerden birini yapabilirsiniz:

  • Önbelleğin boyutunu artırın
  • Önbellek için TTL'yi azaltın
  • Önbelleğe almayı devre dışı bırakın

Daha fazla ayrıntı için bu yapılandırma seçeneklerinin belgelerine bakın .


1
Yorum için teşekkürler. İstisnanın anlamını anlıyorum ve elbette bağlantı verdiğiniz belgeleri okudum, ancak bunun neden yapılandırma değişikliği olmadan 7'den 8'e değiştiğini anlamıyorum. Diğer bir deyişle, varsayılan Dosya Sistemi Kaynağı işleyicisi neden herhangi bir değişikliğe başvurmadan 8'den 7'ye kadar farklı olabilir ve bir başlangıç ​​hatasının bildirilmesi ve sözde düzeltilmesi şüphelidir.
iainmac999

1
Belki taşıma kılavuzunu - özellikle tomcat.apache.org/migration-8.html#Web_application_resources - okumuş olsaydınız , işler daha net olurdu.
Mark Thomas

Dokümantasyonun a) bu önbelleğe hangi kaynakların girdiğini ve nedenini açıklamak (bununla ilgili birçok yanlış anlama var!) Ve b) farklı ayarların ne gibi bir etkisi olabileceğini (örneğin, her bir web uygulamasının önbellek ayarını körü körüne yapmak) yardımcı olabilirdi. oldukça büyük bir ton hafızayı yiyebilir) ve bunu nasıl düzgün bir şekilde ayarlayabilirim. Uygulamanın kendisi tarafından kullanılan statik kaynakların önbelleğe alınması ile kullanıcı aracıları tarafından talep edilen ve yalnızca uygulama tarafından teslim edilen statik dosyalar arasında kod ve yapılandırmada bir ayrım olsaydı da yardımcı olurdu.
volkerk

4

Bu, mesajın günlüklerde görünmesine neden olan koşulları çözmediği anlamında bir çözüm değildir, ancak mesaj aşağıdakilere eklenerek bastırılabilir conf/logging.properties:

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

Bu, UYARI düzeyinde olan "Kaynak eklenemiyor" günlüklerini filtreler.

Benim görüşüme göre a WARNING, mutlaka ele alınması gereken bir hata değildir, ancak istenirse göz ardı edilebilir.


8
Haha. bu sorunu çözmez. Sadece göstermiyor. O NE LAN!
T3rm1

Bu, kendi başına önemli bir sorun olabilecek aşırı kayıt sorununu çözer. İşlerin çoğu kişi için yeterince iyi çalıştığı önceki tomcat sürümlerinin davranışına geri döner, dolayısıyla bu anlamda sorunu "çözer". Devabc'nin cevabının çok güzel bir şekilde kapsadığı tomcat önbelleğini gerçekten ayarlama sorununu ele almıyor.
volkerk
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.