Tomcat 8 Throw - org.apache.catalina.webresources.Cache.getResource ไม่สามารถเพิ่มทรัพยากรได้


112

ฉันเพิ่งอัปเกรด Tomcat จากเวอร์ชัน 7.0.52 เป็น 8.0.14

ฉันได้รับสิ่งนี้สำหรับไฟล์ภาพนิ่งจำนวนมาก:

org.apache.catalina.webresources.Cache.getResourceไม่สามารถเพิ่มทรัพยากรที่ [/base/1325/WA6144-150x112.jpg] ไปยังแคชได้เนื่องจากมีพื้นที่ว่างไม่เพียงพอหลังจากการขับไล่รายการแคชที่หมดอายุ - พิจารณาเพิ่มขนาดสูงสุด ของแคช

ฉันไม่ได้ระบุการตั้งค่าทรัพยากรใด ๆ และฉันไม่ได้รับสิ่งนี้สำหรับ 7.0.52

ฉันพบการกล่าวถึงสิ่งนี้ที่เกิดขึ้นเมื่อเริ่มต้นในรายงานข้อบกพร่องที่ได้รับการแก้ไขแล้ว สำหรับฉันสิ่งนี้ไม่ได้เกิดขึ้นเมื่อเริ่มต้น แต่เกิดขึ้นตลอดเวลาเมื่อมีการร้องขอทรัพยากร

มีใครมีปัญหานี้อีกไหม

อย่างน้อยก็พยายามปิดการใช้งานแคช แต่ฉันไม่พบตัวอย่างวิธีระบุไม่ให้ใช้แคช แอตทริบิวต์ได้หายไปจากบริบทใน Tomcat เวอร์ชัน 8 ได้ลองเพิ่มทรัพยากร แต่ไม่สามารถรับ config ที่ถูกต้องได้

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

ขอบคุณ.


ไม่มีการตอบกลับ - ฉันเดาว่าต้องเป็นคนเดียวที่มีปัญหานี้
iainmac999

2
วิธีแก้ไขอยู่ที่: serverfault.com/questions/644415/…
Dmitry

1
เกี่ยวกับแอตทริบิวต์ที่ขาดหายไปในบริบท Tomcat 8 นี่คือข้อความที่ตัดตอนมาจากคู่มือการย้ายข้อมูล (เน้นของฉัน): " การปรับโครงสร้างทรัพยากรยังส่งผลให้แอตทริบิวต์จำนวนหนึ่งถูกลบออกจากการใช้งานบริบทเริ่มต้น (org.apache.catalina.core .StandardContext) ขณะนี้แอตทริบิวต์ต่อไปนี้อาจถูกกำหนดค่าผ่านการใช้งานทรัพยากรที่ใช้โดยเว็บแอปพลิเคชัน " ข้อมูลเพิ่มเติมในที่เกี่ยวข้องGUID การโยกย้าย
informatik01

@ iainmac999 ไม่เคยเลือกคำตอบที่ถูกต้องหลังจาก 2 ปีเราสามารถตกลงว่ามันใช้ได้ทั้งสองวิธีหรือไม่?
davidjmcclelland

คำตอบ:


161

ใน$CATALINA_BASE/conf/context.xmlบล็อกเพิ่มของคุณด้านล่างก่อนหน้านี้</Context>

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

สำหรับข้อมูลเพิ่มเติม: http://tomcat.apache.org/tomcat-8.0-doc/config/resources.html


11
ผู้อ่านแต่ละคนอาจต้องการปรับค่า cacheMaxSize นั้นเป็นค่าที่น้อยกว่า 100 megs
Eric Spiegelberg

จนถึงตอนนี้ข้อความแสดงข้อผิดพลาดกำลังท่วมบันทึกคอนโซลของฉัน ตอนนี้มันชัดเจน ขอบคุณ
Abubacker Siddik

152

ฉันมีปัญหาเดียวกันเมื่ออัปเกรดจาก Tomcat 7 เป็น 8: คำเตือนบันทึกจำนวนมากอย่างต่อเนื่องเกี่ยวกับแคช

1. คำตอบสั้น ๆ

เพิ่มสิ่งนี้ภายในContextองค์ประกอบ xml ของคุณ$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 mbyte) ดังนั้นให้กำหนดขนาดให้สูงกว่านี้ กว่าปรับแต่งการตั้งค่าที่เหมาะสมที่สุดที่คำเตือนหายไป โปรดทราบว่าคำเตือนอาจกลับมาอีกครั้งภายใต้สถานการณ์การจราจรที่สูงขึ้น

1.1 สาเหตุ (คำอธิบายสั้น ๆ )

ปัญหาเกิดจาก Tomcat ไม่สามารถเข้าถึงขนาดแคชเป้าหมายได้เนื่องจากรายการแคชที่น้อยกว่า TTL ของรายการเหล่านั้น ดังนั้น Tomcat จึงไม่มีรายการแคชเพียงพอที่อาจหมดอายุได้เนื่องจากมันใหม่เกินไปจึงไม่สามารถเพิ่มแคชได้เพียงพอและส่งคำเตือนออกมา

ปัญหาไม่ปรากฏใน Tomcat 7 เนื่องจาก Tomcat 7 ไม่แสดงคำเตือนในสถานการณ์นี้ (ทำให้คุณและฉันใช้การตั้งค่าแคชที่ไม่ดีโดยไม่ได้รับแจ้ง)

ปัญหาจะปรากฏขึ้นเมื่อได้รับคำขอ HTTP จำนวนมากสำหรับทรัพยากร (โดยปกติจะเป็นแบบคงที่) ในช่วงเวลาสั้น ๆ เมื่อเทียบกับขนาดและ TTL ของแคช หากแคชมีขนาดถึงสูงสุด (10mb โดยค่าเริ่มต้น) โดยมีขนาดมากกว่า 95% พร้อมรายการแคชใหม่ (ใหม่หมายถึงน้อยกว่า 5 วินาทีในแคช) กว่าที่คุณจะได้รับข้อความเตือนสำหรับแต่ละ webResource ที่ Tomcat พยายาม เพื่อโหลดในแคช

1.2 ข้อมูลเพิ่มเติม

ใช้ JMX หากคุณต้องการปรับแต่ง cacheMaxSize บนเซิร์ฟเวอร์ที่รันอยู่โดยไม่ต้องรีบูตเครื่อง

การแก้ไขที่เร็วที่สุดคือการปิดการใช้งานแคชอย่างสมบูรณ์: <Resources cachingAllowed="false" />แต่นั่นเป็นอันดับต่ำสุดดังนั้นให้เพิ่ม cacheMaxSize ตามที่ฉันอธิบายไว้

2. คำตอบแบบยาว

2.1 ข้อมูลความเป็นมา

WebSourceเป็นไฟล์หรือไดเรกทอรีในโปรแกรมประยุกต์บนเว็บ ด้วยเหตุผลด้านประสิทธิภาพ Tomcat สามารถแคช WebSources สูงสุดของแคชทรัพยากรแบบคงที่ (ทรัพยากรทั้งหมดในทั้งหมด) เป็นค่าเริ่มต้น 10240 กิโลไบต์ (10 Mbyte) webResource ถูกโหลดลงในแคชเมื่อมีการร้องขอ webResource (ตัวอย่างเช่นเมื่อโหลดภาพนิ่ง) จากนั้นเรียกว่ารายการแคช ทุกรายการแคชมีTTL (เวลาที่ใช้งานจริง) ซึ่งเป็นเวลาที่อนุญาตให้รายการแคชอยู่ในแคช เมื่อ TTL หมดอายุรายการแคชจะมีสิทธิ์ลบออกจากแคช ค่าเริ่มต้นของ cacheTTL คือ 5,000 มิลลิวินาที (5 วินาที)

มีข้อมูลเพิ่มเติมที่จะบอกเกี่ยวกับการแคช แต่ไม่เกี่ยวข้องกับปัญหา

2.2 สาเหตุ

รหัสต่อไปนี้จากคลาส Cacheจะแสดงนโยบายการแคชโดยละเอียด:

152   // เนื้อหาจะไม่ถูกแคช แต่เรายังต้องการข้อมูลเมตาขนาด
153 long delta = cacheEntry getSize (); ขนาด
154 . addAndGet (เดลต้า);
156 if (size. get ()> maxSize) {
157 // ประมวลผลทรัพยากรที่ไม่ได้เรียงลำดับเพื่อความรวดเร็ว เทรดแคช
158 // ประสิทธิภาพ (รายการที่อายุน้อยกว่าอาจถูกขับออกไปก่อนที่เก่ากว่า
159 // รายการ) เพื่อความรวดเร็วเนื่องจากนี่อยู่บนเส้นทางวิกฤตสำหรับ
160 // การประมวลผลคำขอ
161 เป้าหมายขนาดยาว =
162 maxSize * (100 - TARGET_FREE_PERCENT_GET) / 100;
163 newSize ยาว = ขับไล่ (
164 targetSize, resourceCache. values (). iterator ());
165 if (newSize> maxSize) {
166 // ไม่สามารถสร้างพื้นที่เพียงพอสำหรับทรัพยากรนี้
167 // ลบออกจากแคช
168 removeCacheEntry (เส้นทาง);
169 ล็อก เตือน (sm. getString ("cache.addFail", เส้นทาง));
170 }
171 }

เมื่อโหลด webResource โค้ดจะคำนวณขนาดใหม่ของแคช หากขนาดที่คำนวณได้ใหญ่กว่าขนาดสูงสุดเริ่มต้นจะต้องลบรายการแคชมากกว่าหนึ่งรายการขึ้นไปมิฉะนั้นขนาดใหม่จะเกินค่าสูงสุด ดังนั้นโค้ดจะคำนวณ "targetSize" ซึ่งเป็นขนาดที่แคชต้องการให้คงอยู่ (ตามค่าที่เหมาะสม) ซึ่งเป็นค่าเริ่มต้น 95% ของค่าสูงสุด ในการเข้าถึง targetSize นี้รายการจะต้องถูกลบ / ขับออกจากแคช ทำได้โดยใช้รหัสต่อไปนี้:

215   private  longขับไล่ ( long targetSize, Iterator < CachedResource > iter) { 
217 long now = System. currentTimeMillis (); ยาว
219 newSize = size. รับ (); 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 = ขนาด. รับ ();
233 }
235 ส่งคืน newSize;
236 }

ดังนั้นรายการแคชจะถูกลบออกเมื่อ TTL หมดอายุและยังไม่ถึง targetSize

หลังจากความพยายามในการเพิ่มแคชโดยการลบรายการแคชรหัสจะทำ:

165   if (newSize> maxSize) { 
166 // ไม่สามารถสร้างพื้นที่เพียงพอสำหรับทรัพยากรนี้
167 // ลบออกจากแคช
168 removeCacheEntry (เส้นทาง);
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 ปัญหา

ดังที่ข้อความแจ้งเตือนปัญหาคือ

พื้นที่ว่างไม่เพียงพอหลังจากขับไล่รายการแคชที่หมดอายุ - ให้พิจารณาเพิ่มขนาดสูงสุดของแคช

หากเว็บแอปพลิเคชันของคุณโหลด webResources ที่ไม่ได้เชื่อมต่อจำนวนมาก (โดยประมาณสูงสุดของแคชโดยค่าเริ่มต้น 10mb) ภายในเวลาอันสั้น (5 วินาที) คุณจะได้รับคำเตือน

ส่วนที่สับสนคือ Tomcat 7 ไม่แสดงคำเตือน สิ่งนี้เกิดจากรหัส Tomcat 7 นี้:

1606   // เพิ่มรายการใหม่ไปยังแคช
1607 ที่ ซิงโครไนซ์ (แคช) {
1608 // ตรวจสอบขนาดแคชและลบองค์ประกอบหากใหญ่เกินไป
1609 ถ้า ((แคชค้นหา (ชื่อ) == null ) && แคชจัดสรร (รายการขนาด) ) {
1610 แคช โหลด (รายการ);
1611 }
1612 }

รวมกับ:

231   ในขณะที่ (toFree> 0) { 
232 ถ้า (พยายาม == maxAllocateIterations) {
233 // ให้ขึ้นไม่มีการเปลี่ยนแปลงในปัจจุบันแคช
234 ผลตอบแทน เท็จ ;
235 }

ดังนั้น Tomcat 7 จึงไม่ส่งคำเตือนใด ๆ เลยเมื่อไม่สามารถเพิ่มแคชได้ในขณะที่ Tomcat 8 จะส่งคำเตือนออกมา

ดังนั้นหากคุณใช้ Tomcat 8 ด้วยการกำหนดค่าการแคชเริ่มต้นเดียวกันกับ Tomcat 7 และคุณได้รับคำเตือนใน 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" หมายถึงขนาดแคชที่เพิ่มขึ้นระบุเป็นกิโลไบต์ ค่าเริ่มต้นคือ 10240 (10 mbyte) ดังนั้นกำหนดขนาดให้สูงกว่านี้

คุณจะต้องปรับแต่งการตั้งค่าที่เหมาะสม โปรดทราบว่าปัญหาอาจกลับมาเมื่อคุณมีคำขอปริมาณการใช้งาน / ทรัพยากรเพิ่มขึ้นอย่างกะทันหัน

เพื่อหลีกเลี่ยงการรีสตาร์ทเซิร์ฟเวอร์ทุกครั้งที่คุณต้องการลองขนาดแคชใหม่คุณสามารถเปลี่ยนได้โดยไม่ต้องรีสตาร์ทโดยใช้ JMX

ในการเปิดใช้งาน JMXให้เพิ่มสิ่งนี้$CATALINA_BASE/conf/server.xmlในServerองค์ประกอบ: <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ค่าลงโดยสิ่งที่ต่ำกว่า 5,000 มิลลิวินาทีและปรับแต่งเพื่อการตั้งค่าที่เหมาะสมที่สุด

ตัวอย่างเช่น: <Resources cacheTtl="2000" />

สิ่งนี้มาพร้อมกับการมีและการเติมแคชใน ram โดยไม่ต้องใช้มัน

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)


เพิ่มแคช? ฉันสงสัยว่ามันจะได้ผล ... ฉันเห็นสิ่งนี้: maxSize ส่วนตัวยาว = 10 * 1024 * 1024; ในแหล่งที่มา grepcode.com/file/repo1.maven.org/maven2/org.apache.tomcat/…
HoaPhan

คุณพบคำตอบหรือไม่ว่าทำไม tomcat8 ถึงมีคำเตือนแคชท่วม
PHP Avenger

@HoaPhan 10 * 1024 * 1024 สูงสุด 10mb สำหรับแคชทั้งหมด ขึ้นอยู่กับปริมาณการใช้งานของ webapp ซึ่งสามารถเข้าถึงได้ภายในไม่กี่วินาที เพิ่มไปไกลพอจะทำงาน
Devabc

@PHPAvenger Tomcat 7 ไม่ได้เตือนเลยในสถานการณ์นี้ในขณะที่ Tomcat 8 ทำดังนั้นจึงสามารถมองว่าเป็นคุณสมบัติการเตือน ปัญหาคือมันเตือนไม่ใช่แค่ครั้งเดียว แต่ในทุกคำขอทรัพยากรที่จะแคช จะเป็นการปรับปรุงเพื่อเตือนหลังจากช่วงเวลาหนึ่งหรือการเข้าถึงเป้าหมายแคชเท่านั้น
Devabc

@Devabc คำตอบไร้ที่ติ! คลาสสิกมาก!
Gaurav

9

คุณมีทรัพยากรแบบคงที่มากกว่าที่แคชมีที่ว่าง คุณสามารถดำเนินการอย่างใดอย่างหนึ่งต่อไปนี้:

  • เพิ่มขนาดของแคช
  • ลด TTL สำหรับแคช
  • ปิดการใช้งานการแคช

สำหรับรายละเอียดเพิ่มเติมโปรดดูเอกสารสำหรับตัวเลือกการกำหนดค่าเหล่านี้


1
ขอบคุณสำหรับความคิดเห็น ฉันเข้าใจความหมายของข้อยกเว้นและแน่นอนว่าฉันได้อ่านเอกสารที่คุณเชื่อมโยงถึงอย่างไรก็ตามฉันไม่เข้าใจว่าทำไมสิ่งนี้จึงเปลี่ยนจาก 7 เป็น 8 โดยไม่มีการเปลี่ยนแปลงการกำหนดค่า นั่นคือเหตุใดตัวจัดการทรัพยากรระบบไฟล์เริ่มต้นจึงแตกต่างกันใน 8 ถึง 7 โดยไม่มีการอ้างอิงถึงการเปลี่ยนแปลงใด ๆ และเป็นที่น่าสงสัยว่ามีการรายงานข้อบกพร่องในการเริ่มต้นระบบและได้รับการแก้ไขแล้ว
iainmac999

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

วิธีนี้ช่วยแก้ปัญหาการตัดไม้มากเกินไปซึ่งอาจเป็นปัญหาสำคัญได้ด้วยตัวมันเอง มันกลับไปสู่พฤติกรรมของแมวตัวผู้รุ่นก่อนซึ่งสิ่งต่าง ๆ ทำงานได้ดีเพียงพอสำหรับหลาย ๆ คนดังนั้นในแง่นั้นมัน "แก้" ปัญหาได้ มันไม่ได้แก้ปัญหาในการปรับแต่งแคชของแมวตัวผู้ซึ่งคำตอบของ devabc นั้นครอบคลุมเป็นอย่างดี
volkerk
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.