2012-11-28 49 views
23

में सक्षम है Iclipse Juno में जावा ईई वेब अनुप्रयोग विकसित कर रहा हूं। मैंने पोस्टग्रेएसक्यूएल डेटाबेस के साथ जेडीबीसी कनेक्शन पूल (org.apache.tomcat.jdbc.pool) का उपयोग करने के लिए टोमकैट को कॉन्फ़िगर किया है। जेडीबीसी कनेक्शन पूल कनेक्शन से बाहर चला जाता है जब संदर्भ पुनः लोड = "सत्य" टोमकैट

<?xml version="1.0" encoding="UTF-8"?> 
<Context> 
    <!-- Configuration for the Tomcat JDBC Connection Pool --> 
    <Resource name="jdbc/someDB" 
     type="javax.sql.DataSource" 
     auth="Container" 
     factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" 
     driverClassName="org.postgresql.Driver" 
     url="jdbc:postgresql://localhost:5432/somedb" 
     username="postgres" 
     password="12345" 
     maxActive="100" 
     minIdle="10" 
     initialSize="10" 
     validationQuery="SELECT 1" 
     validationInterval="30000" 
     removeAbandoned="true" 
     removeAbandonedTimeout="60" 
     abandonWhenPercentageFull="50" /> 
</Context> 

मेरा आवेदन ग्रहण का उपयोग कर बिलाव को तैनात किया जाता है स्वचालित रूप से, और बिलाव के context.xml में एक विशेषता फिर से लोड करने के लिए सेट है करने के लिए "सही": यहाँ मेरी परियोजना की META-INF/context.xml में विन्यास कर रहे हैं वेब अनुप्रयोग को फिर से लोड करता है, तो एक परिवर्तन का पता चला है:

<Context reloadable="true">

मैंने देखा है हर बार ऊपर उल्लेख किया है कि स्वत: पुनः लोड (PostgreSQL db करने के लिए 10 अधिक कनेक्शन हो रहा है क्योंकि वेब ऐप्लिकेशन की context.xml initialSize में = आरक्षित है " 10 ")। तो बाद 10 बदल जाता है एक PSQLException फेंक दिया जाता है:

org.postgresql.util.PSQLException: FATAL: sorry, too many clients already 
... 

मैं मैन्युअल रूप से पुन: प्रारंभ तो बिलाव - सब कुछ ठीक है और सिर्फ 10 कनेक्शन आरक्षित हैं।

क्या कोई इस मुद्दे के आसपास के रास्ते को जानता है, इसलिए पुनः लोड करने योग्य सेट के साथ "सत्य" के साथ विकसित करना संभव हो सकता है और संदर्भ को फिर से लोड होने पर हर कनेक्शन को पूलिंग का कारण नहीं बन सकता है?

किसी भी मदद की सराहना करेंगे।

पीएस अपाचे बिलाव संस्करण 7.0.32

+1

अधिकतर http://stackoverflow.com/questions/8435359/why-do-connections-persist-when-i-undeploy-a-webapp-using-the-tomcat-7-jdbc-conn का डुप्लिकेट – Isaac

+1

@Isaac "यह बिलाव 7.0.11 से सही किया गया है", लेकिन मैं 7.0.32 और अभी भी एक ही परिणाम है। तो मूल रूप से यह एक बग है? – informatik01

+0

एक रिग्रेशन हो सकता है। यदि आप पूरी तरह से सुनिश्चित हैं कि आप सभी कनेक्शन को खाली कर रहे हैं, और समस्या अभी भी होती है, तो मैं बग रिपोर्ट को फिर से खोलने के लिए कहूंगा। – Isaac

उत्तर

30

समाधान (tl; डॉ)

इस समस्या को हल करने के लिए, मान "पास" संसाधन तत्व के साथ एक विशेषता closeMethod (दस्तावेज here) जोड़ने context.xml फ़ाइल में। विशेषता closeMethod को

<Context> 
    <!-- Configuration for the Tomcat JDBC Connection Pool --> 
    <Resource name="jdbc/someDB" 
     type="javax.sql.DataSource" 
     auth="Container" 
     factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" 
     driverClassName="org.postgresql.Driver" 
     url="jdbc:postgresql://localhost:5432/somedb" 
     username="postgres" 
     password="12345" 
     maxActive="100" 
     minIdle="10" 
     initialSize="10" 
     validationQuery="SELECT 1" 
     validationInterval="30000" 
     removeAbandoned="true" 
     removeAbandonedTimeout="60" 
     abandonWhenPercentageFull="50" 
     closeMethod="close" /> 
</Context> 

वेतन ध्यान:

यहाँ मेरी /META-INF/context.xml फ़ाइल का सही सामग्री है। मैंने इसका परीक्षण किया और अब कनेक्शन की संख्या को context.xml फ़ाइल में परिभाषित अनुसार रखा गया है!

नोट
एक पल (JNDI से संबंधित) कि का ध्यान रखा जा सकता है नहीं है। पूर्ण विवरण के लिए अद्यतन 3 देखें।


लांग जवाब

ठीक है, मैं अपाचे बिलाव committor Konstantin Kolinko के लिए ऊपर समाधान धन्यवाद पाया। मैंने एएसएफ बगजिला और पर अपाचे टॉमकैट बग के रूप में this issue की सूचना दी और यह (अपडेट 1 देखें) पर एक बग नहीं है।

=== अद्यतन 1 (2012-12-03) उर्फ ​​"अ न्यू होप" ===

ठीक है, यह अभी भी निकला एक बग किया जाना है।Mark Thomas, अपाचे बिलाव 7 रिलीज प्रबंधक, confirmed कि (उद्धरण):।

"यह JDBC-पूल में एक स्मृति रिसाव बग है PoolCleaner उदाहरणों ConnectionPool को बनाए रखने के संदर्भ में किया जा रहा GC'd से रोक रहे हैं ।
...
यह ट्रंक और 7.0.x में तय किया गया है और 7.0.34 बाद में शामिल किया जाएगा। "

तो आप एक पुराने बिलाव संस्करण (7.0.34 से भी कम) है, इसके बाद के संस्करण समाधान,, अपाचे बिलाव संस्करण 7.0.34 के साथ शुरू का उपयोग अन्यथा, वहाँ एक मैं वर्णित की तरह कोई मुद्दा नहीं होना चाहिए। (अद्यतन 2 देखें)

=== अद्यतन 2 (2014-01-13) उर्फ ​​"मुद्दा स्ट्राइक्स बैक" ===

यह मुद्दा शुरू में my bug report में वर्णित की तरह लगता है अभी भी मौजूद है यहां तक ​​कि वर्तमान में नवीनतम अपाचे बिलाव संस्करण 7.0.50 के लिए और मैं भी बिलाव 7.0.47 के साथ reproduced (यह उनका कहना है के लिए Miklos Krivan करने के लिए धन्यवाद)। अब हालांकि बिलाव कभी कभी फिर से लोड करने के बाद अतिरिक्त कनेक्शन बंद करने के लिए प्रबंधन करता है, और कभी कभी कनेक्शन की संख्या एक बार पुनः लोड करने के बाद बढ़ रहे हैं और उसके बाद स्थिर रखा, लेकिन अंत में इस व्यवहार अभी भी विश्वसनीय नहीं है।

मैं अभी भी को प्रारंभिक रूप से वर्णित समस्या (फिर से इतना आसान नहीं: पुन: लोड करने की आवृत्ति से संबंधित हो सकता है) को पुन: उत्पन्न कर सकता है। लगता है कि यह समय का मामला है, अर्थात जैसे अगर बिलाव पुनः लोड के बाद पर्याप्त समय है, यह कनेक्शन पूल कम या ज्यादा एकदम सही ढंग से प्रबंधन करता है। मार्क थॉमस उसके comment (उद्धरण) में उल्लेख किया है: "closeMethod के लिये दस्तावेज के अनुसार, उस विधि पूरी तरह से मौजूद है संसाधनों है कि अन्यथा जीसी द्वारा मुक्त किया जाएगा मुक्त तेजी लाने के लिए।" (उद्धरण के अंत), और ऐसा लगता है कि गति परिभाषित कारक है।

कॉन्स्टेंटिन कोलिंको द्वारा प्रस्तुत समाधान का उपयोग करते समय (closeMethod = "close" का उपयोग करने के लिए) सबकुछ ठीक काम करता है, और सुरक्षित कनेक्शन की संख्या को संदर्भ.xml फ़ाइल में परिभाषित किया गया है। तो ऐसा प्रतीत होता है कि संदर्भ पुनः लोड करने के बाद कनेक्शन से बाहर निकलने से बचने के लिए closeMethod = "close" का उपयोग करना केवल सही तरीका है (फिलहाल)।

=== अद्यतन 3 (2014-01-13) उर्फ ​​"बिलाव रिलीज प्रबंधक की वापसी" ===

व्यवहार अद्यतन 2 में वर्णित के पीछे रहस्य सुलझ गया है। मार्क थॉमस (टॉमकैट रिलीज मैनेजर) से reply प्राप्त करने के बाद अब अधिक जानकारी साफ़ कर दी गई है। मुझे उम्मीद है कि यह आखिरी अपडेट है। तो बग वास्तव में तय किया गया था के रूप में अद्यतन 1. मैं यहाँ मार्क जबाब से अनिवार्य हिस्सा पोस्टिंग कर रहा हूँ उद्धरण के रूप में (जोर मेरा) में उल्लेख किया गया था:

वास्तविक स्मृति रिसाव पाया, जबकि इस बग की जांच कर रही है टिप्पणियों के अनुसार टिप्पणियों के अनुसार 7.0.34 में तय किया गया है।

कनेक्शनों का मुद्दा पुनः लोड पर बंद नहीं किया जा रहा है जेएनडीआई संसाधनों के लिए जे 2 ईई विनिर्देश का परिणाम है और बग रिपोर्ट का यह हिस्सा इसलिए अमान्य है। मैं प्रतिबिंबित करने के लिए है कि स्मृति रिसाव कि अस्तित्व में थे तय किया गया है तय को इस बग के राज्य को बहाल कर रहा हूँ।

क्यों विफलता तुरंत घनिष्ठ संबंध के बाद पुनः लोड अमान्य है, J2EE विनिर्देशन कंटेनर संसाधन यह अब आवश्यक है बताने के लिए के लिए कोई तंत्र प्रदान करता है पर विस्तार करने के लिए। इसलिए सभी कंटेनर कर सकते हैं संसाधन के लिए स्पष्ट संदर्भ है और कचरा संग्रहण (जो पूल को बंद करने और जुड़े कनेक्शन ट्रिगर किया जाएगा) के लिए प्रतीक्षा करें। कचरा संग्रह कई बार को JVM द्वारा द्वारा निर्धारित किया जाता है, इसलिए कनेक्शन को संदर्भित करने के बाद को कचरा के रूप में बंद करने के लिए अनिश्चित समय लगता है संग्रह कुछ समय के लिए नहीं हो सकता है।

बिलाव बिलाव विशिष्ट JNDI विशेषता closeMethod जो जब एक संदर्भ बंद कर दिया है एक JNDI संसाधन की स्पष्ट पास को गति प्रदान करने के लिए इस्तेमाल किया जा सकता है जोड़ा गया है। हैं जीसी संसाधनों को साफ करने के लिए इंतज़ार कर रहे नहीं है स्वीकार्य तो बस इस पैरामीटर का उपयोग करें। बिलाव डिफ़ॉल्ट रूप से इस का उपयोग नहीं करता के रूप में यह के लिए अप्रत्याशित और अवांछित दुष्प्रभाव कुछ JNDI संसाधनों हो सकता है।

यदि आप जेएनडीआई संसाधनों को बताने के लिए प्रदान की गई मानक तंत्र देखना चाहते हैं, तो उन्हें अब जे 2 ईई विशेषज्ञ समूह लॉबी करने की आवश्यकता है।

निष्कर्ष

बस (, लेकिन सिर्फ मामले में, मन में JNDI संबंधित मुद्दा यह है कि कर सकते हैं सैद्धांतिक रूप से का उपयोग करने से उत्पन्न होती हैं रखने के लिए) इस पोस्ट की शुरुआत में प्रस्तुत समाधान का उपयोग करें।


वैकल्पिक समाधान

Michael Osipov उसकी CloseableResourceListener का उपयोग कर सुझाव दिया है, जो वेब अनुप्रयोगों की undeployment दौरान छोड़ दिया खुला संसाधनों की वजह से मेमोरी लीक से बचाता है। तो आप इसे भी आज़मा सकते हैं।


अस्वीकरण
अद्यतन के लिए उपनाम Star Wars फिल्म श्रृंखला से प्रेरित थे। सभी अधिकार उनके संबंधित मालिकों के हैं।

+1

दुर्भाग्य से बिलाव 7.0.35 एक ही परेशानी होती है लेकिन closeMethod = "बंद" मूल्य मेरी समस्या हल। –

+1

टॉमकैट 7.0.47 में भी एक ही समस्या है लेकिन closeMethod = "close" सही काम करता है। –

+0

@MiklosKrivan अद्यतन में इस समस्या का अंतिम विवरण देखें 3. – informatik01