क्या आपको server.xml या संदर्भ.xml में डेटाबेस कनेक्शन गुण सेट करना चाहिए


79

मैं एक स्प्रिंग वेब एप्लिकेशन के लिए जेएनडीआई का उपयोग करके डेटाबेस कनेक्शन गुण स्थापित करने का प्रयास कर रहा हूं।

मैं नीचे दो दृष्टिकोणों पर विचार कर रहा हूं:

दृष्टिकोण 1:

आपके स्प्रिंग कॉन्फ़िगरेशन में आपके पास कुछ इस तरह हो सकता है:

<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/facs"/>

फिर आपकी वेबऐप /META-INF/context.xml फाइल में भी आपके पास कुछ ऐसा ही होना चाहिए:

<?xml version='1.0' encoding='utf-8'?>

<!-- antiResourceLocking="true" -->
<Context path="/podd-apn"
         reloadable="true"
         cachingAllowed="false"
         antiResourceLocking="true"
         >

  <Resource name="jdbc/facs"              
            type="javax.sql.DataSource" username="${database.username}" password="${database.password}"
            driverClassName="org.postgresql.Driver" 
            url="${database.url}"
            maxActive="8" maxIdle="4"
            global="jdbc/facs" 
            />


</Context>

और आपके web.xml में आपको कुछ इस तरह होना चाहिए:

<!-- JNDI -->
  <resource-ref>
    <description>FACs Datasource</description>
    <res-ref-name>jdbc/facs</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref> 


दृष्टिकोण 2:

इस तरह से स्प्रिंग संदर्भ में सेटअप:

<jee:jndi-lookup id="dbDataSource"
   jndi-name="jdbc/DatabaseName"
   expected-type="javax.sql.DataSource" />

आप टॉमनेट के सर्वर में JNDI संसाधन की घोषणा कर सकते हैं। इस तरह से कुछ का उपयोग करके:

<GlobalNamingResources>
  <Resource name="jdbc/DatabaseName" auth="Container" type="javax.sql.DataSource"
              username="dbUsername" password="dbPasswd"
              url="jdbc:postgresql://localhost/dbname"
              driverClassName="org.postgresql.Driver"
              initialSize="5" maxWait="5000"
              maxActive="120" maxIdle="5"
              validationQuery="select 1"
              poolPreparedStatements="true"/>
</GlobalNamingResources/>

और जेएनडीआई संसाधन को टॉमकैट के वेब संदर्भ से संदर्भित करें। xml इस प्रकार है:

<ResourceLink name="jdbc/DatabaseName"
   global="jdbc/DatabaseName"
   type="javax.sql.DataSource"/>


मेरा सवाल है कि डेटाबेस गुणों को रखने के लिए सबसे अच्छी जगह कहां है? वे में रखा जाना चाहिए server.xml या context.xml ?

इसके अलावा, अगर मेरे पास 2 डेटाबेस हैं, तो क्या मुझे दो कॉन्फ़िगरेशन का उपयोग करना चाहिए?

इसके अलावा, यह सीधे सर्वर या xml या संदर्भ.xml में उन्हें रखने के लिए सबसे अच्छा अभ्यास है? या क्या मुझे टॉमकैट प्रबंधक जीयूआई कंसोल के माध्यम से कॉन्फ़िगर करने की आवश्यकता है?

धन्यवाद!

जवाबों:


27

मैं एक तीसरा दृष्टिकोण पसंद करता हूं जो उपयोगकर्ता1016403 द्वारा वर्णित दृष्टिकोण 1 और दृष्टिकोण 2 से सर्वश्रेष्ठ लेता है ।

दृष्टिकोण ३

  1. पर डेटाबेस गुण सहेजें server.xml
  2. server.xmlवेब अनुप्रयोग से डेटाबेस गुणों का संदर्भ लेंMETA-INF/context.xml

दृष्टिकोण 3 लाभ

जबकि पहला बिंदु सुरक्षा कारणों से उपयोगी है, दूसरा बिंदु वेब एप्लिकेशन से सर्वर गुण मानों को संदर्भित करने के लिए उपयोगी है, भले ही सर्वर गुण मान बदल जाएंगे।

इसके अलावा वेब एप्लिकेशन द्वारा उनके उपयोग से सर्वर पर संसाधन परिभाषाओं को अलग-अलग संगठनों के साथ ऐसे कॉन्फ़िगरेशन को स्केलेबल बनाया जाता है जहां विभिन्न टीमें अलग-अलग स्तरों / परतों पर काम करती हैं: सर्वर प्रशासक टीम डेवलपर्स टीम के साथ संघर्ष किए बिना काम कर सकती है यदि व्यवस्थापक एक ही साझा करता है प्रत्येक संसाधन के लिए डेवलपर के साथ JNDI नाम।

दृष्टिकोण 3 कार्यान्वयन

JNDI नाम परिभाषित करें jdbc/ApplicationContext_DatabaseName

टॉमकैट के jdbc/ApplicationContext_DatabaseNameविभिन्न गुणों और मूल्यों को server.xmlइस तरह से उपयोग करने की घोषणा करें:

<GlobalNamingResources>
  <Resource name="jdbc/ApplicationContext_DatabaseName" auth="Container" type="javax.sql.DataSource"
              username="dbUsername" password="dbPasswd"
              url="jdbc:postgresql://localhost/dbname"
              driverClassName="org.postgresql.Driver"
              initialSize="5" maxWait="5000"
              maxActive="120" maxIdle="5"
              validationQuery="select 1"
              poolPreparedStatements="true"/>
</GlobalNamingResources/>

विशेषता में निर्दिष्ट एप्लिकेशन-निजी JNDI संदर्भ द्वारा jdbc/ApplicationContext_DatabaseNameवेब एप्लिकेशन से गुणों को लिंक करें :META-INF/context.xmljava:comp/env/name

<Context path="/ApplicationContext" ... >
  <!--
    "global" attribute links to GlobalNamingResources in the ${catalina.base}/conf/server.xml (server administrator team)
    "name" attribute is relative to the application-private JNDI context java:comp/env/ and is looked up from the java web application (application developer team)
  -->
  <ResourceLink global="jdbc/ApplicationContext_DatabaseName" name="jdbc/DatabaseName" type="javax.sql.DataSource"/>
</Context>

अंत में, JNDI संसाधन का उपयोग करने के लिए, jdbc/DatabaseNameवेब एप्लिकेशन की तैनाती विवरणक में JNDI नाम निर्दिष्ट करें :

<resource-ref>
    <description>DatabaseName's Datasource</description>
    <res-ref-name>jdbc/DatabaseName</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref> 

और वसंत संदर्भ में:

<jee:jndi-lookup id="DatabaseNameDataSource"
   jndi-name="jdbc/DatabaseName"
   expected-type="javax.sql.DataSource" />

दृष्टिकोण 3 कमियां

यदि JNDI नाम बदल जाता है, तो दोनों को server.xmlऔर META-INF/context.xmlवसीयत को संपादित करना होगा और एक तैनाती आवश्यक होगी; फिर भी यह परिदृश्य दुर्लभ है।

दृष्टिकोण 3 भिन्नता

एक वेब एप्लिकेशन द्वारा उपयोग किए जाने वाले कई डेटा स्रोत

बस टॉमकैट के लिए विन्यास जोड़ें server.xml:

<GlobalNamingResources>
  <Resource name="jdbc/ApplicationContext_DatabaseName1" ... />
  <Resource name="jdbc/ApplicationContext_DatabaseName2" ... />
  ...
</GlobalNamingResources/>

विशेषता में निर्दिष्ट META-INF/context.xmlएप्लिकेशन-निजी JNDI संदर्भ द्वारा लिंक वेब एप्लिकेशन जोड़ें :java:comp/env/name

<Context path="/ApplicationContext" ... >
  <ResourceLink global="jdbc/ApplicationContext_DatabaseName1" name="jdbc/DatabaseName1" ... />
  <ResourceLink global="jdbc/ApplicationContext_DatabaseName2" name="jdbc/DatabaseName2" ... />
  ...
</Context>

अंत में वेब एप्लिकेशन की तैनाती विवरणक में JNDI संसाधनों के उपयोग को जोड़ें:

<resource-ref>
    <description>DatabaseName1's Datasource</description>
    <res-ref-name>jdbc/DatabaseName1</res-ref-name> ... 
</resource-ref> 
<resource-ref>
    <description>DatabaseName2's Datasource</description>
    <res-ref-name>jdbc/DatabaseName2</res-ref-name> ... 
</resource-ref>
...

और वसंत संदर्भ में:

<jee:jndi-lookup id="DatabaseName1DataSource"
   jndi-name="jdbc/DatabaseName1" ... />
<jee:jndi-lookup id="DatabaseName2DataSource"
   jndi-name="jdbc/DatabaseName2" ... />
...


एक ही सर्वर पर कई वेब एप्लिकेशन द्वारा उपयोग किए जाने वाले कई डेटा स्रोत

बस टॉमकैट के लिए कॉन्फ़िगरेशन जोड़ें server.xml:

<GlobalNamingResources>
  <Resource name="jdbc/ApplicationContextX_DatabaseName1" ... />
  <Resource name="jdbc/ApplicationContextX_DatabaseName2" ... />
  <Resource name="jdbc/ApplicationContextY_DatabaseName1" ... />
  <Resource name="jdbc/ApplicationContextY_DatabaseName2" ... />
  ...
</GlobalNamingResources/>

अन्य विन्यास पिछले बदलाव के मामले से अलग होना चाहिए।


एक ही डेटाबेस के कई डेटा स्रोत एक ही सर्वर पर कई वेब एप्लिकेशन द्वारा उपयोग किए जाते हैं

ऐसे मामले में एक टॉमकैट के server.xmlविन्यास जैसे:

<GlobalNamingResources>
  <Resource name="jdbc/ApplicationContextX_DatabaseName" ... />
  <Resource name="jdbc/ApplicationContextY_DatabaseName" ... />

दो अलग-अलग वेब अनुप्रयोगों में समाप्त होता है META-INF/context.xml जैसे:

<Context path="/ApplicationContextX" ... >
  <ResourceLink global="jdbc/ApplicationContextX_DatabaseName" name="jdbc/DatabaseName" ... />
</Context>

और पसंद करें:

<Context path="/ApplicationContextY" ... >
  <ResourceLink global="jdbc/ApplicationContextY_DatabaseName" name="jdbc/DatabaseName" ... />
</Context>

इसलिए किसी को इस तथ्य के बारे में चिंतित हो सकता है कि एक ही name="jdbc/DatabaseName"देखा जाता है, और फिर एक ही सर्वर पर तैनात दो अलग-अलग अनुप्रयोगों द्वारा उपयोग किया जाता है: यह एक समस्या नहीं है क्योंकि jdbc/DatabaseNameएक अनुप्रयोग-निजी JNDI संदर्भ है java:comp/env/, इसलिए इसका ApplicationContextX उपयोगjava:comp/env/ नहीं किया जा सकता है (डिजाइन द्वारा) से जुड़े संसाधन को देखें global="jdbc/ApplicationContextY_DatabaseName"

बेशक अगर आप इस चिंता के बिना अधिक आराम महसूस करते हैं तो आप एक अलग नामकरण रणनीति का उपयोग कर सकते हैं:

<Context path="/ApplicationContextX" ... >
  <ResourceLink global="jdbc/ApplicationContextX_DatabaseName" name="jdbc/applicationXprivateDatabaseName" ... />
</Context>

और पसंद करें:

<Context path="/ApplicationContextY" ... >
  <ResourceLink global="jdbc/ApplicationContextY_DatabaseName" name="jdbc/applicationYprivateDatabaseName" ... />
</Context>

आपके "एक ही डेटाबेस पर कई वेब एप्लिकेशन द्वारा उपयोग किए जाने वाले डेटाबेस के लिए कई डेटा स्रोत" परिदृश्य के बारे में प्रश्न ... <Resource name="jdbc/ApplicationContextX_DatabaseName" ... /> <Resource name="jdbc/ApplicationContextY_DatabaseName" ... /> यदि संसाधन कनेक्शन पूल थे, तो क्या इससे आपको दो अलग-अलग पूल मिलेंगे, प्रति वेबपेज एक? जबकि, अगर मैं दोनों webapps से एक संसाधन से जुड़ा हूं, तो सिर्फ एक कनेक्शन पूल होगा, सही? किसी एक को पसंद करने के लिए कोई कारण? (अलग डीबी कनेक्शन पूल प्रति वेबएप बनाम एक कनेक्शन पूल जो सभी वेबएप द्वारा साझा किया गया है)? धन्यवाद।
रेबेकाह

1
@ रीबेकाह - क्यू 1: यदि संसाधन कनेक्शन पूल थे, तो क्या इससे आपको दो अलग-अलग पूल मिलेंगे, प्रति वेबैप एक? A1: हाँ यह होगा।
तारिंगमबेरिनी

1
@ रीबेकाह - क्यू 2: जबकि, अगर मैं दोनों वेबएप से एक संसाधन से जुड़ा हूं, तो सिर्फ एक कनेक्शन पूल होगा, सही? A2: सही है।
तारिंगमबेरिनी

2
@ रीबेकाह - क्यू 3: किसी एक को दूसरे से पसंद करने का कोई कारण? (अलग डीबी कनेक्शन पूल प्रति वेबएप बनाम एक कनेक्शन पूल जो सभी वेबएप द्वारा साझा किया गया है)? A3: मैं "अलग DB कनेक्शन पूल प्रति एक webapp" पसंद करता हूँ क्योंकि मैं webAppX का गहन उपयोग webAppX के कनेक्शन पूल की थकावट के कारण webAppY के धीमेपन में समाप्त नहीं होता; डेटाबेस की निगरानी और लॉगिंग सिस्टम को वेबएपएक्स और वेबएपीवाई अनुरोधों के बीच अंतर नहीं किया जा सकता है, इसलिए समस्याओं को समझना और अलग करना मुश्किल या बदतर असंभव होगा।
तारिंगमबेरिनी

23

YOUR_APP.xml फ़ाइल

मुझे एप्रोच 2 पसंद है (सब कुछ डालें (न केवल कुछ विशेषताओं को कॉन्फिगर करें), बल्कि उन्हें ग्लोबल server.xmlया ग्लोबल में रखने के बजाय context.xmlआपको इसे अपने टॉमकैट में एप्लिकेशन-विशिष्ट फ़ाइल में रखना चाहिए ।context.xml.default YOUR_APP.xml

YOUR_APP.xmlफ़ाइल में स्थित है $catalinaHome/conf/<engine>/<host>(उदाहरण के लिए conf/Catalina/localhost/YOUR_APP.xml)।

एप्लिकेशन विशिष्ट में कॉन्फ़िगरेशन YOUR_APP.xmlकेवल विशिष्ट एप्लिकेशन के लिए उपलब्ध है।

MuleSoft द्वारा प्रकाशित गाइड देखें । और आधिकारिक दस्तावेज, टॉमकैट कॉन्फ़िगरेशन संदर्भ , संदर्भ कंटेनर के लिए पृष्ठ देखें

उस प्रलेखन को उद्धृत करने के लिए:

व्यक्तिगत संदर्भ तत्वों को स्पष्ट रूप से परिभाषित किया जा सकता है:

•…

• निर्देशिका में व्यक्तिगत फ़ाइलों (".xml" एक्सटेंशन के साथ) में $CATALINA_BASE/conf/[enginename]/[hostname]/। संदर्भ पथ और संस्करण फ़ाइल के आधार नाम (फ़ाइल नाम कम .xml एक्सटेंशन) से लिया जाएगा।

•…


2
उर उत्तर के लिए धन्यवाद। यदि मैं हमारे अनुप्रयोगों META-INF / संदर्भ.xml में सभी गुण रखता हूं? यह रखने के लिए सबसे अच्छी जगह है?
user1016403

5
मुझे नहीं लगता कि कुछ गुण मान INSIDE (META-INF / reference.xml में जांच के लिए) रखने से आवेदन एक अच्छा दृष्टिकोण है, क्योंकि तब आपको गुणों को बदलने पर एप्लिकेशन को फिर से स्थापित करना और तैनात करना होगा। - तो यह लगभग वैसा ही होगा जैसे बिना किसी गुण का उपयोग किए और मानों को सीधे वसंत config.xml में रखना
Ralph

फिर उन्हें रखने के लिए अनुशंसित स्थान कौन सा है?
user1016403

2
मैं सिर्फ संदर्भ .xml.default का उपयोग करके सभी ऐप के लिए इन्हें परिभाषित करने के बजाय, आप एक ही फ़ोल्डर में yourapp.xml जैसी एप्लिकेशन-विशिष्ट संदर्भ कॉन्फ़िगरेशन फ़ाइलों का उपयोग कर सकते हैं, जो आपको एक ही युद्ध के दो तैनाती बिंदुओं की अनुमति देता है विभिन्न डेटाबेस।
usethe4ce

1
सहायक उत्तर नहीं। यह सिर्फ एक प्राथमिकता बताता है और कोई औचित्य प्रदान नहीं करता है।
डेविड्स

10

दृष्टिकोण ४

JNDI का उपयोग करने के बजाय मैं .propertiesफ़ाइलों के साथ काम करता हूं और कॉन्फ़िगरेशन समय के बजाय प्रोग्राम इनिशियलाइज़ेशन के दौरान जटिल ऑब्जेक्ट का निर्माण करता हूं ।

आप पहले से ही स्प्रिंग का उपयोग करते हैं और इसका निर्माण आसान DataSourceहै:

<context:property-placeholder location="classpath:app.properties"/>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="oracle.jdbc.OracleDriver"/>
    <property name="url" value="jdbc:oracle:thin:@${db.host}:${db.port}:${db.user}"/>
    <property name="username" value="${db.user}"/>
    <property name="password" value="${db.pass}"/>
</bean>

मैं पूरी तरह सहमत हूँ साथ राल्फ तैनाती वर्णनकर्ता का उपयोग करने के , $CATALINA_BASE/conf/[enginename]/[hostname]/$APP.xmlलेकिन इसके बजाय जेएनडीआई मुझे सादा की-वैल्यू फ़ाइल पसंद है!

वसंत के साथ सेम के खेतों में गुणों को ऊपर ले जाना आसान है:

@Value("${db.user}") String defaultSchema;

JNDI के बजाय:

@Inject ApplicationContext context;
Enviroment env = context.getEnvironment();
String defaultSchema = env.getProperty("db.user");

ध्यान दें कि ईएल इसे अनुमति देता है (डिफ़ॉल्ट मान और गहन पुनरावर्ती प्रतिस्थापन):

@Value('${db.user:testdb}') private String dbUserName;

<property name='username' value='${db.user.${env}}'/>

.propertiesफ़ाइल को बाहरी करने के लिए मैं आधुनिक Tomcat 7 का उपयोग करता हूं जिसमें org.apache.catalina.loader.VirtualWebappLoerer है :

<Loader className="org.apache.catalina.loader.VirtualWebappLoader"
        virtualClasspath="/srv/web/app/"/>

तो तुम्हारे भक्त भरते हैं virtualClasspath स्थानीय बाहरी पूर्ण रास्तों से हैं, जो कि प्रति अनुप्रयोग अलग होती है और स्थानीय app.propertiesको उस dir में ।

यह सभी देखें:


0

आप परीक्षण, एकीकरण परीक्षण, उत्पादन के लिए विभिन्न एप्लिकेशन कॉन्फ़िगरेशन के लिए JNDI URL समर्थन का भी उपयोग कर सकते हैं।

<Context>
...
<Resource auth="Container" factory="com.benasmussen.jndi.url.URLFactory" 
name="url/MyUrl" type="java.net.URL" url="file:///your/path/to/file"/>
...
</Context>

<jee:jndi-lookup id="myUrl" jndi-name="java:comp/env/url/MyUrl" expected-type="java.net.URL" />

GitHub प्रोजेक्ट Tomcat JNDI URL समर्थन की जाँच करें, Tomcat सर्वर के लिए JNDI URL समर्थन को सक्षम करने के लिए।


0

चरण 1: संदर्भ। xml

    <Context path="/projectname">
  <Resource auth="Container" 
            driverClassName="com.mysql.jdbc.Driver"
            logAbandoned="true" 
            maxActive="100" ``
            maxIdle="30" 
            maxWait="10000" 
            name="refname" 
            removeAbandoned="true" 
            removeAbandonedTimeout="60" 
            type="javax.sql.DataSource" 
            url="jdbc:mysql://localhost:8080/dbname" 
            username="root"
            password="root"/>
</Context>

चरण 2: web.xml

<resource-ref>
        <description>DB Connection</description>
        <res-ref-name>refname</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>

चरण 3: कनेक्शन प्राप्त करने के लिए एक वर्ग बनाएं

Connection connection = null;        
            Context context = (Context) new InitialContext().lookup("java:comp/env");
            DataSource ds = (DataSource) context.lookup("refname");
            connection = ds.getConnection();

सब कुछ सेट है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.