java - जेडीबीसी कनेक्शन पूल कनेक्शन से बाहर चला जाता है जब संदर्भ पुनः लोड="सत्य" टोमकैट में सक्षम है



eclipse tomcat (1)

समाधान (टीएल; डॉ)

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

मेरी /META-INF/context.xml फ़ाइल की सही सामग्री यहां दी गई है:

<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>

विशेषता बंद करें विधि पर ध्यान दें । मैंने इसका परीक्षण किया और अब कनेक्शन की संख्या को संदर्भित किया गया है जैसा कि context.xml फ़ाइल में परिभाषित किया गया है!

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

लंबा जवाब

ठीक है, मैंने उपरोक्त समाधान को अपाचे टॉमकैट कमिटोर कॉन्स्टेंटिन कोलिंको को धन्यवाद दिया। मैंने एएसएफ बगजिला पर अपाचे टॉमकैट बग के रूप में इस मुद्दे की सूचना दी और यह पता चला कि यह एक बग नहीं है (अद्यतन 1 देखें)।

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

खैर, यह अभी भी एक बग बन गया । अपाचे टॉमकैट 7 रिलीज मैनेजर मार्क थॉमस confirmed कि (उद्धरण):

"यह जेडीबीसी-पूल में एक मेमोरी लीक बग है। पूल क्लेनर उदाहरण कनेक्शन कनेक्शन के संदर्भों को जीसीएडी होने से रोकते हैं।
...
यह ट्रंक और 7.0.x में तय किया गया है और इसे 7.0.34 में शामिल किया जाएगा। "

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

=== अद्यतन 2 (2014-01-13) उर्फ ​​"समस्या वापस आती है " ===

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

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

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

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

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

इस बग की जांच करते समय मिली वास्तविक स्मृति रिसाव को # 4 से # 6 के अनुसार 7.0.34 के बाद तय किया गया है।

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

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

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

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

निष्कर्ष

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

दूसरा तरीका

माइकल CloseableResourceListener ने अपने CloseableResourceListener का उपयोग करने का सुझाव दिया, जो वेब अनुप्रयोगों के अनावश्यकता के दौरान बाएं खुले संसाधनों के कारण स्मृति रिसाव को रोकता है। तो आप इसे भी आज़मा सकते हैं।

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

मैं एक्लिप्स जूनो में जावा ईई वेब एप्लिकेशन विकसित कर रहा हूं। मैंने पोस्टग्रेएसक्यूएल डेटाबेस के साथ जेडीबीसी कनेक्शन पूल (org.apache.tomcat.jdbc.pool) का उपयोग करने के लिए टोमकैट को कॉन्फ़िगर किया है। मेरे प्रोजेक्ट के मेटा-आईएनएफ / context.xml में कॉन्फ़िगरेशन यहां दिए गए हैं:

<?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 में एक विशेषता पुनः लोड करने योग्य एक वेब पता स्वचालित रूप से फिर से लोड करने के लिए "सत्य" पर सेट किया गया है यदि कोई परिवर्तन पता चला है:

<Context reloadable="true">

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

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

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

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

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

पीएस अपाचे टॉमकैट संस्करण 7.0.32





connection-pooling