टॉमकैट 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 कारण (संक्षिप्त विवरण)
यह समस्या टॉमकैट द्वारा कैश प्रविष्टियों के कारण अपने लक्ष्य कैश आकार तक पहुंचने में असमर्थ होने के कारण है जो उन प्रविष्टियों के टीटीएल से कम है। तो टॉमकैट के पास पर्याप्त कैश प्रविष्टियां नहीं थीं, जो इसे समाप्त कर सकती थीं, क्योंकि वे बहुत ताज़ा थे, इसलिए यह पर्याप्त कैश मुक्त नहीं कर सका और इस तरह चेतावनी जारी करता है।
समस्या टॉमकैट 7 में दिखाई नहीं दी क्योंकि टॉमकैट 7 ने केवल इस स्थिति में चेतावनी नहीं दी थी। (आपको और मुझे सूचित किए बिना खराब कैश सेटिंग का उपयोग करने के लिए।)
कैश के आकार और TTL की तुलना में सापेक्ष कम समय अवधि में संसाधनों (आमतौर पर स्थिर) के लिए एक बड़ी मात्रा में HTTP अनुरोध प्राप्त करते समय समस्या प्रकट होती है। यदि कैश ताजा कैश प्रविष्टियों के साथ 95% से अधिक आकार के साथ अपने अधिकतम (डिफ़ॉल्ट रूप से 10mb) तक पहुंच रहा है (ताजा साधन कैश में 5 सेकंड से कम है), तो आप प्रत्येक webResource के लिए एक चेतावनी संदेश प्राप्त करेंगे जो टॉमकैट कोशिश करता है कैश में लोड करने के लिए।
1.2 वैकल्पिक जानकारी
अगर आपको रिबूट किए बिना चल रहे सर्वर पर cacheMaxSize को ट्यून करने की आवश्यकता है, तो JMX का उपयोग करें।
सबसे तेज़ फिक्स कैश को पूरी तरह से अक्षम करना होगा: <Resources cachingAllowed="false" />
लेकिन यह सब-ऑप्टिमल है, इसलिए कैशमैक्स को बढ़ाएं जैसा कि मैंने अभी बताया है।
2. लंबा उत्तर
2.1 पृष्ठभूमि की जानकारी
एक WebSource एक वेब अनुप्रयोग में एक फ़ाइल या निर्देशिका है। प्रदर्शन कारणों के लिए, Tomcat WebSources को कैश कर सकता है। स्थैतिक संसाधन कैश (कुल में सभी संसाधन) की अधिकतम डिफ़ॉल्ट रूप से 10240 kbyte (10 mbyte) है। WebResource कैश में लोड किया जाता है जब webResource अनुरोध किया जाता है (उदाहरण के लिए जब स्थिर छवि लोड हो रहा है), तो इसे कैश प्रविष्टि कहा जाता है। प्रत्येक कैश प्रविष्टि में एक टीटीएल (रहने का समय) होता है, जो कि कैश प्रविष्टि को कैश में रहने की अनुमति है। जब TTL समाप्त हो जाता है, तो कैश प्रविष्टि कैश से निकाले जाने योग्य है। CacheTTL का डिफ़ॉल्ट मान 5000 मिलीसेकंड (5 सेकंड) है।
कैशिंग के बारे में बताने के लिए और भी बहुत कुछ है, लेकिन यह समस्या के लिए अप्रासंगिक है।
२.२ कारण
कैश क्लास से निम्न कोड कैशिंग नीति को विस्तार से दिखाता है:
152 // सामग्री को कैश नहीं किया जाएगा, लेकिन हमें अभी भी मेटाडेटा का आकार
153 लंबा डेल्टा = कैशइंट्री चाहिए। getSize ();
154 आकार। addAndGet (डेल्टा);
156 अगर (आकार। मिलता है ()> अधिकतम आकार ) {
157 // प्रक्रिया संसाधन गति के लिए अनियंत्रित । ट्रैक्स कैश
158 // कार्यकुशलता (पुरानी प्रविष्टियों को पुराने
159 // लोगों से पहले बेदखल किया जा सकता है) क्योंकि यह
160 के लिए महत्वपूर्ण पथ पर है।
161 लंबे लक्ष्य को संसाधित करने का अनुरोध करता है =
162 अधिकतम आकार * (100 - TARGET_FREE_EFERENT_GET) / 100;
163 लंबे नए आकार = बेदखल (
164 टारगेटसाइज़, रिसोर्सकैच। मान । ) ( इटरेटर ) ();
165 अगर (newSize> maxSize) {
166 // इस संसाधन के लिए पर्याप्त स्थान बनाने में असमर्थ
167 // इसे कैश से निकालें
168 removeCacheEntry (पथ);
169 लॉग। चेतावनी (sm। getString ("cache.addFail", पथ));
170 }
171 }
WebResource लोड करते समय, कोड कैश के नए आकार की गणना करता है। यदि परिकलित आकार डिफ़ॉल्ट अधिकतम आकार से बड़ा है, तो एक या अधिक कैश्ड प्रविष्टियों को हटाना होगा, अन्यथा नया आकार अधिकतम से अधिक हो जाएगा। तो कोड एक "टारगेटसाइज" की गणना करेगा, जो कि वह आकार है जिसके तहत कैश (अधिकतम के रूप में) नीचे रहना चाहता है, जो कि डिफ़ॉल्ट रूप से अधिकतम 95% है। इस लक्ष्य तक पहुंचने के लिए, प्रविष्टियों को कैश से निकाला / निकाला जाना चाहिए। यह निम्नलिखित कोड का उपयोग करके किया जाता है:
215 निजी लंबा बेदखल ( लंबा लक्ष्य तय करें, Iterator < CakedResource > iter) {
217 लंबा अब = सिस्टम। currentTimeMillis ();
219 लंबा नया आकार = आकार। मिल ();
221 जबकि (newSize> targetSize && आईटीईआर। HasNext ()) {
222 CachedResource संसाधन = आईटीईआर। अगला ();
224 // Do कुछ भी है कि टीटीएल के भीतर चेक किया गया है समाप्त नहीं
225 अगर (संसाधन। GetNextCheck ()> अब) {
226 जारी रखें ;
227 }
229 // कैश से प्रविष्टि निकालें
230 हटाएं कैशइंट्री (संसाधन। getWebappPath ());
232 newSize = आकार। मिल ();
233 }
235 वापसी नया
236 }
इसलिए जब उसके TTL की समय सीमा समाप्त हो जाती है, तो एक कैश प्रविष्टि को हटा दिया जाता है और टारगेट को अभी तक पूरा नहीं किया गया है।
कैश प्रविष्टियों को हटाकर कैश मुक्त करने के प्रयास के बाद, कोड करेगा:
165 अगर (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 समस्या
इसलिए जैसा कि चेतावनी संदेश कहता है, समस्या है
समय-सीमा समाप्त कैश प्रविष्टियों को निकालने के बाद उपलब्ध अपर्याप्त स्थान - कैश के अधिकतम आकार को बढ़ाने पर विचार करें
यदि आपका वेब एप्लिकेशन बहुत कम समय (5 सेकंड) के भीतर बहुत सारे अनछुए webResources (लगभग अधिकतम कैश के बारे में) लोड करता है, तो आपको चेतावनी मिल जाएगी।
भ्रामक हिस्सा यह है कि टॉमकैट 7 ने चेतावनी नहीं दिखाई। यह बस इस Tomcat 7 कोड के कारण होता है:
1606 // कैश में नई प्रविष्टि जोड़ें
1607 सिंक्रोनाइज़ (कैश) {
1608 // कैश आकार की जाँच करें, और तत्वों को हटा दें यदि बहुत बड़ा
1609 यदि ((कैश। लुकअप (नाम) == null ) && कैश को आवंटित करें (प्रविष्टि । Size) ) {
१६१० कैश। लोड (प्रवेश);
1611 }
1612 }
के साथ संयुक्त:
231 जबकि (toFree> 0) {
232 if (प्रयास == maxAllocateIterations) {
233 // छोड़ दें, वर्तमान कैश में कोई परिवर्तन नहीं किए गए हैं
234 झूठी लौटें ; 235 }
तो टॉमकैट 7 बस किसी भी चेतावनी का उत्पादन नहीं करता है जब यह कैश मुक्त करने में असमर्थ है, जबकि टॉमकैट 8 एक चेतावनी का उत्पादन करेगा।
तो अगर आप Tomcat 8 को Tomcat 7 के समान डिफॉल्ट कैशिंग कॉन्फ़िगरेशन के साथ उपयोग कर रहे हैं, और आपको Tomcat 8 में चेतावनी मिली, तो Tomcat 7 की आपकी (और मेरी) कैशिंग सेटिंग बिना चेतावनी के खराब प्रदर्शन कर रही थीं।
2.4 समाधान
कई समाधान हैं:
- कैश बढ़ाएँ (अनुशंसित)
- TTL को कम करें (अनुशंसित नहीं)
- कैश लॉग चेतावनी को दबाएं (अनुशंसित नहीं)
- कैश निष्क्रिय करें
2.4.1। कैश बढ़ाएँ (अनुशंसित)
जैसा कि यहाँ वर्णित है: http://tomcat.apache.org/tomcat-8.0-doc/config/rescript.html
<Resources cacheMaxSize="XXXXX" />
उस Context
तत्व के भीतर जोड़कर $CATALINA_BASE/conf/context.xml
, जहां "XXXXX" एक बढ़े हुए कैश आकार के लिए खड़ा है, जो किबीट्स में निर्दिष्ट है। डिफ़ॉल्ट 10240 (10 mbyte) है, इसलिए इससे अधिक आकार सेट करें।
आपको इष्टतम सेटिंग्स के लिए ट्यून करना होगा। ध्यान दें कि जब आप अचानक ट्रैफ़िक / संसाधन अनुरोधों में वृद्धि करते हैं तो समस्या वापस आ सकती है।
हर बार जब आप नए कैश आकार का प्रयास करना चाहते हैं तो सर्वर को पुनरारंभ करने से बचने के लिए, आप इसे जेएमएक्स का उपयोग करके पुनरारंभ किए बिना बदल सकते हैं।
करने के लिए 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
। फिर JMX को सर्वर से कनेक्ट करने के लिए jConsole (Java JDK के साथ डिफॉल्ट रूप से शिप) का उपयोग करें और सर्वर चालू होने के दौरान कैशे का आकार बढ़ाने के लिए सेटिंग्स के माध्यम से देखें। इन सेटिंग्स में परिवर्तन तुरंत प्रभावित होना चाहिए।
2.4.2। TTL को कम करें (अनुशंसित नहीं)
लोअर cacheTtl
इष्टतम सेटिंग्स के लिए 5000 मिलीसेकंड से कम कुछ द्वारा मूल्य और धुन।
उदाहरण के लिए: <Resources cacheTtl="2000" />
यह प्रभावी रूप से नीचे आता है और इसे उपयोग किए बिना RAM में कैश भरने के लिए।
2.4.3। कैश लॉग चेतावनी को दबाएं (अनुशंसित नहीं)
के लिए लकड़हारा को निष्क्रिय करने के लिए लॉगिंग कॉन्फ़िगर करें org.apache.catalina.webresources.Cache
।
Tomcat में लॉग इन करने के बारे में अधिक जानकारी के लिए: http://tomcat.apache.org/tomcat-8.0-doc/log.html
2.4.4। कैश निष्क्रिय करें
आप सेटिंग cachingAllowed
पर जाकर कैशे को निष्क्रिय कर सकते हैं false
।
<Resources cachingAllowed="false" />
हालाँकि मुझे याद है कि टॉमकैट 8 के बीटा संस्करण में, मैं कैश को निष्क्रिय करने के लिए जेएमएक्स का उपयोग कर रहा था। (निश्चित रूप से क्यों बिल्कुल नहीं, लेकिन server.xml के माध्यम से कैश को अक्षम करने में समस्या हो सकती है।)