Program Tip

자바 웹 애플리케이션 구성 패턴

programtip 2020. 12. 5. 10:30
반응형

자바 웹 애플리케이션 구성 패턴


여러 환경에서 Java 웹 애플리케이션에 대한 구성 프로파일 변경을 단순화하는 데 사용할 수있는 패턴 또는 우수 사례가 있습니까? 예 : JDBC URL, SOAP 끝점 등

내 질문을 명확히하는 데 도움이되는 약간의 배경 지식으로, 주어진 릴리스주기 동안 6 개의 서로 다른 환경을 통해 이동하는 여러 대형 Java 웹 애플리케이션을 사용합니다. 개발, 통합, QA, 성능 및 결국 여러 프로덕션 서버에 배포됩니다. 각 환경에서 구성을 변경해야합니다. 현재 각 배포에 대한 대부분의 구성 변경은 시간이 많이 걸리고 오류가 발생할 수있는 수동으로 수행됩니다.
이 프로세스에서 수동 개입을 제거 할 수있는 방법이 있습니까?


나는 최근에 .NET으로 더 많이 작업하는 경향이 있으므로 Java는 상당히 녹슬 었습니다. 나는 이것이 약간의 조정으로 모든 언어에서 작동 할 것이라고 확신합니다.

우리는 더 글로벌 구성과 함께 환경 및 / 또는 응용 프로그램 특정 설정을 사용할 수 있도록 .NET 구성 시스템의 확장을 사용합니다. 구성 시스템은 각 시스템에 대해 전역 설정을 사용하여 개발, 베타 또는 프로덕션 (기본값)으로 식별합니다. 순서대로로드 된 파일 세트이며 마지막 파일의 설정이 이전에로드 된 파일에 정의 된 모든 설정을 대체합니다. 파일은 다음 순서로로드됩니다.

  1. 전역 설정
  2. 애플리케이션 별 설정
  3. 애플리케이션 별 환경 재정의

모든 파일은 소스 제어에 있으며 환경이 응용 프로그램이 실행되는 시스템에 정의되어 있기 때문에; 머신 구성이 "베타"로 식별하지 않는 한 "베타"구성에 액세스하지 않기 때문에 실수로 프로덕션 애플리케이션이 개발 데이터베이스를 가리키는 것을 두려워하지 않고 모든 구성 파일을 승격 할 수 있습니다.


이 질문에 답하기 위해 Jakarta Commons Configuration API ( http://commons.apache.org/configuration/ )를 인용 한 사람이 아무도 없다는 사실에 놀랐습니다 . 파일 계층 구조 (또는 XML, JNDI, JDBC 등과 같은 기타 구성 소스)를 가질 수 있습니다. 이것이 Jeremy Seghi가 말한 내용이며 기본값과 로컬 재정의를 모두 가질 수있는 좋은 방법을 제공합니다.

가장 좋은 점은 테스트 된 작업 솔루션이므로 직접 만들 필요가 없다는 것입니다.


내가 사용했거나 만난 몇 가지 가능한 사례는 다음과 같습니다. 이들을 결합하는 것은 일반적으로 실제로 필요합니다.

빌드 할 때 conf 파일의 변수 값 대체

다음은 Apache Ant로이를 수행하는 방법에 대한 예입니다. Ant 속성 ( ${var.name})은 빌드 구성 파일로 제어 할 수 있습니다.

<filterset id="variables.to.replace">
    <filter token="APPNAME" value="${app.name}"/>
    <filter token="WEBAPP-PATH" value="${webapp.path}"/>
    <filter token="ENCRYPT-ALGORITHM" value="${encrypt.algorithm}"/>
    <filter token="ERROR-MAILTO" value="${error.mailTo}"/>
    <!--...-->
</filterset>

<!-- Then, when building & copying the conf, replace the variables: -->
<copy todir="${properties.target.dir}">
    <!-- env specific conf files -->
    <fileset dir="${basedir}/env/${run.env}/webapp/WEB-INF/classes" />
    <filterset refid="variables.to.replace"/>
</copy>

좋은 점은 빌드시 다양한 구성을 세밀하게 제어 할 수 있다는 것입니다. 나쁜 점은이 방법을 여러 다른 구성에 광범위하게 사용하면 시스템이 매우 복잡해지고 유지 관리가 어려워지는 경향이 있다는 것입니다. 또한 conf 파일을 빌드해야한다는 것은 개발주기가 더 느리다는 것을 의미합니다.

webapp 시작시 war 내부에서 conf의 변수 대체

이것은 하나의 가능한 구성이 있더라도 Spring Framework를 사용할 때 일반적으로 수행하는 작업이며 관심사 분리의 이점을 얻습니다. Spring을 사용하면 webapp 시작시 Spring 컨텍스트 내에서 PlaceholderPropertyConfigurer로 conf 값을 대체 할 수 있습니다. 이 경우 어쨌든 올바른 구성을 선택해야합니다. 예를 들어 빌드 시간에 구성 할 수 있습니다.

빌드 시간을 대체하는 것과 비교하여 필요한 경우 압축되지 않은 웹앱의 값을 일시적으로 조작하는 것이 더 쉽습니다. 물론 웹앱을 변경 한 경우에는 웹앱을 재부팅해야하며 웹앱 재배포시 수동 변경 사항이 유지되지 않습니다. Spring은 또한 Spring 컨텍스트로 제한되기 때문에 이것은 예를 들어 web.xml에서 작동하지 않습니다 (그러나 web.xml에 변수를 갖는 것은 아마도 제한 때문에 피해야합니다).

미리 정의 된 파일에서 로컬 conf 읽기

이 접근 방식은 아마도 설정하기 가장 쉬운 방법 일 것입니다. 예를 들어 구성 파일 경로를 발명하고 $HOME/mywebapp/conf.properties시작시 웹앱이이를 읽도록 만드십시오.

여기서 좋은 점은 웹앱을 빌드 / 배포 할 때 conf에 대해 신경 쓸 필요가 없다는 것입니다. 어쨌든, 로컬 conf에 의해 재정의 될 수있는 몇 가지 합리적인 conf 기본값이 있어야합니다.

데이터베이스에 conf 포함

이것은 conf 매개 변수를 재정의하는 가장 유연한 솔루션이지만 경우에 따라 복잡해질 수도 있습니다. namevalue열이 있는 테이블에 conf가 있으면 대부분의 경우에 작동합니다.

물론 데이터베이스 테이블에서 JDBC 연결 URL을 구성 할 수는 없지만 db 연결이 설정된 후 웹 응용 프로그램의 작업에 영향을 미치는 간단한 텍스트 / 숫자 구성에는 좋은 솔루션입니다. 성능 저하를 피하려면 자주 액세스 할 경우 어떻게 든 conf를 캐시해야합니다.

추가 관행

kgiannakakis가 지적한 것처럼 앱에 대한 일종의 구성 진단 페이지를 설정하는데도 도움이됩니다.


이것은 웹 애플리케이션 서버가 제공하는 옵션에 따라 크게 달라집니다. JDBC URL이 다른 JBoss에 대한 여러 환경이 있으며 JNDI 이름은 모든 서버에서 동일하게 유지되며 로컬 인스턴스의 구성 만 변경되므로 빌드마다 문제가 발생하지 않습니다.

짧은 대답은 모범 사례는 구성을 구체화하고 각 서버에 대한 올바른 설정으로 좋은 파일을 유지하고 웹 앱이 해당 구성을 읽도록하는 것입니다. 외부화 및 읽기의 정확한 특성은 특정 구성 및 애플리케이션 서버에 따라 달라집니다.

편집 : 이러한 구성은 덮어 쓰지 않는 방식으로 전쟁 (우리의 경우 귀)의 일부로 존재하지 않습니다.


처음에는 자주 변경되는 모든 구성 설정이 한 곳에서 이루어집니다. 구성을 완료하기 위해 JNDI를 설정하고 데이터베이스 값을 편집하고 속성 파일을 동시에 수정해야하는 경우 정말 어렵습니다. 편집하기 쉽고 모든 것이 올바르게 설정되었는지 확인하기 쉬운 매체를 선호합니다. 속성 파일이 최상의 솔루션이라고 말하고 싶습니다. 쉽게 편집 할 수 있으며 모든 것이 정상인지 확인하기 위해 빠르게 살펴보기 만하면됩니다. 특성 파일을 선택하는 경우 해당 파일의 표준 위치를 신중하게 선택하고 경로에 환경 변수를 지정하십시오.

모든 것이 올바르게 설정되었는지 확인하는 간단한 테스트가있는 경우에도 도움이됩니다. 예를 들어 구성 매개 변수를 표시하고 데이터베이스 또는 원격 서버에 연결 시도와 같은 몇 가지 기본 테스트를 수행하는 테스트 페이지를 가질 수 있습니다.


원하는 좋은 예는 Seam 또는 Grails (Rails에서 빌려 옴)에서 사용됩니다. 기본적으로 prod, dev, test의 세 가지 프로필이 있지만 원하는 경우 더 많이 정의 할 수 있습니다.

Seam에서 프로젝트 빌드는 Ant 파일로 수행됩니다. 내용이 다를 수있는 각 파일은 데이터 소스, SQL 스크립트 또는 속성 파일과 같은 모든 프로필에 대해 정의됩니다.

import-dev.sql
import-prod.sql
import-test.sql

선택한 프로파일로 ant 파일을 실행하면 해당 파일이 선택되고 해당 파일 이름에서 프로파일 이름이 잘립니다.

다음은 타겟에 배치 할 수있는 코드 스 니펫입니다.

<copy tofile="${war.dir}/WEB-INF/classes/import.sql" 
      file="${basedir}/resources/import-${profile}.sql"/>

JDBC url, driver names can be externalized to properties files (of course with profile names as suffixes)

<filterset id="persistence">
     <filter token="transactionManagerLookupClass" value="${transactionManagerLookupClass}"/>

<copy tofile="${war.dir}/WEB-INF/classes/META-INF/persistence.xml" 
     file="${basedir}/resources/META-INF/persistence-${profile}.xml">
     <filterset refid="persistence"/>
</copy>

or values of properies you can pass to ant build call from command line. This is short example what is in Seam done.

Another option is to used Maven. In maven way it done by properties and by profiles, but you can use also separate modules to split configuration and create other modules with main functionality. Typical use case examples of maven properties and profiles are run configuration for multiple databases, deployment servers etc. It's even harder when you want to create configuration for different vendors, but for Maven that isn't a problem :)

Great example of using maven profiles is this post form Carlos Sanchez blog.

To sum up I strongly recomend to look up Ant/Seam an Maven parametrization (profiles). Those solutions have another advantage: ant or maven script can be run in CI server (like Hudson) and let run/test simultaneously all your profiles.


You can use the Component Configuration Pattern in your language of choice

It is described in the POSA books (I think that in the 4th volume)

(in java you can use the commons-configuration component ).


There are a few possible ways to approach this:

  • use property files like you do, but add a "meta properties" file that is used to select the property file used by defining a map between an environment value (for instance localhost hostname) onto the property file name to load.

  • put your properties into a database and define the database connection to the property tables in your application server as resource that is picked up by your web-app.

  • don't put the property files in your .war or .ear, but create a properties-deployhost.jar archives containing the property files per target host. bind the appropriate .jar file to the deployed web-app by adding it to the class path (for instance via shared libraries in the application server configuration per web-app.)

Only the first of these does not need extra manual steps when deploying at the expense of having to update your config source and building new deploy files when your target systems are renamed.

I'm sure lots of variantions on these and your approach are possible, what is the best choice depends on your situation.


What we do works pretty well.

On startup, our programs read a configuration file in a hardcoded path. Let's say it's:

/config/fun_prog/config.xml

Each program has a different hard coded path (FunProgram is in fun_prog, Super Server is in sup_serv, whatever), so we don't have to worry about them walking over each other.

The XML files are read by a little configuration library we created. The XML file contains the DB connection information, usually mail server configuration data, email addresses to send notifications to, whether it should operate in test mode, URLs of external services, etc.

So when we need to make changes, we copy the config file, edit what we want, and restart the program. Since we have a standard server setup, any program can be deployed on any server by just copying these files around (and the neccessary httpd.conf tinkering).

It's not fancy, but it works very well. It's extremely simple to understand, add new configuration options, backup, and edit. Works on all platforms (unix is obvious, Windows translates paths starting with / into c:\ so it works without edits there too).

Our workstations basically run the same software as the server, just with a few changes in that config file.


Please take a look at this URL: http://issues.apache.org/jira/browse/CONFIGURATION-394

The Configuration framework which we're looking for it is something on top of Apache Commons Configuration and must support Concurrency Issues, JMX issues and most of stores(e.g .properties file, .xml files or PreferencesAPI).

What weblogic team provides on 'Administration Console' is intersting which through it you can have transactional(atomic) updates on configurations so that are registered listeners be notified.

The Apache guys insist that this project is out of scopes of Commons Configuration, maybe!

I've attached a simple configuration framework, take look please.

참고URL : https://stackoverflow.com/questions/1568985/java-web-application-configuration-patterns

반응형