Programing

server.xml 또는 context.xml에서 데이터베이스 연결 속성을 설정해야합니까?

lottogame 2020. 10. 13. 07:16
반응형

server.xml 또는 context.xml에서 데이터베이스 연결 속성을 설정해야합니까?


Spring 웹 애플리케이션에 JNDI를 사용하여 데이터베이스 연결 속성을 설정하려고합니다.

다음과 같은 두 가지 접근 방식을 고려하고 있습니다.

접근법 1 :

Spring 구성에는 다음과 같은 것이있을 수 있습니다.

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

그런 다음 webapp /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 :

다음과 같이 Spring 컨텍스트에서 설정하십시오.

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

다음과 같이 Tomcat의 server.xml에서 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/>

다음과 같이 Tomcat의 웹 context.xml에서 JNDI 리소스를 참조하십시오.

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


내 질문은 데이터베이스 속성을 유지하는 가장 좋은 장소는 어디입니까? server.xml 또는 context.xml 에 있어야합니까 ?

또한 2 개의 데이터베이스가있는 경우 2 개의 구성을 사용해야합니까?

또한 server.xml 또는 context.xml에 직접 배치하는 것이 가장 좋은 방법입니까? 아니면 Tomcat Manager GUI 콘솔을 통해 구성해야합니까?

감사!


저는 user1016403이 설명하는 접근법 1접근법 2 에서 가장 좋은 세 번째 접근법을 선호합니다 .

접근 3

  1. 데이터베이스 속성을 server.xml
  2. server.xml웹 애플리케이션에서 데이터베이스 속성 참조META-INF/context.xml

접근 방식 3 가지 이점

첫 번째 지점은 보안상의 이유로 유용하지만 두 번째 지점은 서버 속성 값이 변경 되더라도 웹 응용 프로그램에서 서버 속성 값을 참조하는 데 유용합니다.

또한 서버의 리소스 정의를 웹 애플리케이션에서 사용하는 것과 분리하면 서로 다른 팀이 서로 다른 계층 / 계층에서 작업하는 다양한 복잡성을 가진 조직 전체에서 이러한 구성을 확장 할 수 있습니다. 관리자가 동일한 것을 공유하는 경우 서버 관리자 팀은 개발자 팀과 충돌하지 않고 작업 할 수 있습니다. 각 자원에 대한 개발자와 함께 JNDI 이름.

접근 방식 3 구현

JNDI 이름을 정의하십시오 jdbc/ApplicationContext_DatabaseName.

다음과 같은 것을 사용하여 jdbc/ApplicationContext_DatabaseNameTomcat에서의 다양한 속성과 값을 선언하십시오 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/>

링크 jdbc/ApplicationContext_DatabaseName웹 응용 프로그램에서의 특성을 META-INF/context.xml응용 프로그램 - 개인 JNDI 컨텍스트에 의해 java: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> 

그리고 Spring 컨텍스트에서 :

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

3 가지 단점 접근

JNDI 이름이 변경되면 server.xml을 모두 META-INF/context.xml편집해야하며 배포가 필요합니다. 그럼에도 불구하고이 시나리오는 드뭅니다.

3 가지 변형에 접근

하나의 웹 애플리케이션에서 사용하는 많은 데이터 소스

Tomcat에 구성을 추가하기 만하면됩니다 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>
...

그리고 Spring 컨텍스트에서 :

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


동일한 서버의 많은 웹 응용 프로그램에서 사용하는 많은 데이터 소스

Tomcat에 구성을 추가하기 만하면됩니다 server.xml.

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

다른 구성은 이전 변형 사례에서 추론 할 수 있어야합니다.


동일한 서버의 많은 웹 애플리케이션에서 사용하는 동일한 데이터베이스에 대한 많은 데이터 소스

이 경우 Tomcat의 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>

YOUR_APP.xml 파일

I prefer Approach 2 (put everything (not only some attribute in the config), but instead of placing them in the global server.xml or global context.xml you should place it in the application-specific context.xml.default YOUR_APP.xml file in your Tomcat.

The YOUR_APP.xml file is located in $catalinaHome/conf/<engine>/<host> (for example conf/Catalina/localhost/YOUR_APP.xml).

The configuration in application specific YOUR_APP.xml is only available for the specific application.

See the guide published by MuleSoft. And see the official documentation, Tomcat Configuration Reference, page for The Context Container

To quote that documentation:

Individual Context elements may be explicitly defined:

• …

• In individual files (with a ".xml" extension) in the $CATALINA_BASE/conf/[enginename]/[hostname]/ directory. The context path and version will be derived from the base name of the file (the file name less the .xml extension).

• …


Approach 4

Instead of using JNDI I work with .properties files and build complex object during program initialization instead on configuration time.

You already use Spring and it is easy construct DataSource by:

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

I completely agree with Ralph with using deployment descriptor in $CATALINA_BASE/conf/[enginename]/[hostname]/$APP.xmlbut instead JNDI I like plain key-value file!

With Spring injecting above properties into bean fields are easy:

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

instead of JNDI:

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

Note also that EL allow this (default values and deep recursive substitution):

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

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

To externalize .properties file I use modern Tomcat 7 that has org.apache.catalina.loader.VirtualWebappLoader:

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

So your devops fill virtualClasspath with local external full paths which is separate per application and put local app.propertiesto that dir.

See also:


You also can use JNDI URL support for different application configuration for test, integration test, production.

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

Check out the GitHub project Tomcat JNDI URL Support to enable JNDI URL support for Tomcat servers.


step 1: context.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>

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

Step 3 : create a class to get connection

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

Everything is set

참고URL : https://stackoverflow.com/questions/15064260/should-you-set-up-database-connection-properties-in-server-xml-or-context-xml

반응형