#EAP7

[JBoss EAP 7] 데이터소스 패스워드 암호화 완벽 가이드: Password Vault 구성 및 적용 (Windows/Linux)

JBoss EAP 7.x 환경에서 평문으로 저장되는 데이터소스 비밀번호를 보호하기 위해 Password Vault를 구성하는 방법을 정리합니다. Windows와 Linux 환경, 그리고 Standalone과 Domain 모드 각각에 대한 설정법을 포괄하며, KeyStore 생성부터 VAULT 문자열 적용까지의 전체 프로세스를 다룹니다.

1. 프로세스 개요 (Process Overview)

Vault 구성은 크게 4단계로 진행됩니다.

  1. KeyStore 생성: 암호화 키를 저장할 물리적 파일(.keystore) 생성
  2. Vault 초기화 및 암호화: 비밀번호를 암호화하고 JBoss 설정에 필요한 파라미터 생성
  3. JBoss Vault 설정: 생성된 KeyStore와 JBoss를 연동 (standalone.xml 또는 host.xml)
  4. 데이터소스 적용: 평문 비밀번호를 암호화된 문자열(${VAULT::...})로 교체

2. KeyStore 생성 (Generate KeyStore)

Java의 keytool을 사용하여 JCEKS 형식의 키스토어를 생성합니다.

Windows 환경

keytool.exe -genseckey ^
  -alias "vault" ^
  -storetype "jceks" ^
  -keyalg "AES" ^
  -keysize "128" ^
  -storepass "passw0rd" ^
  -keypass "passw0rd" ^
  -validity "7300" ^
  -keystore "D:\app\was\JBoss\vault\vault.keystore"

Linux 환경

./keytool -genseckey \
  -alias "vault" \
  -storetype "jceks" \
  -keyalg "AES" \
  -keysize "128" \
  -storepass "passw0rd" \
  -keypass "passw0rd" \
  -validity "7300" \
  -keystore "/app/was/JBoss/vault/vault.keystore"

3. 비밀번호 암호화 실행 (Vault Tool)

JBoss `bin` 디렉토리에 있는 vault 스크립트를 사용하여 실제 DB 패스워드를 암호화합니다.

Windows (vault.bat)

vault.bat --keystore "D:\app\was\JBoss\vault\vault.keystore" ^
  --keystore-password "passw0rd" ^
  --alias "vault" ^
  --vault-block "vb" ^
  --attribute "dbpw" ^
  --sec-attr "RealDBPassword!" ^
  --enc-dir "D:\app\was\JBoss\vault" ^
  --iteration "44" ^
  --salt "JBo72ssv"

Linux (vault.sh)

./vault.sh --keystore "/app/was/JBoss/vault/vault.keystore" \
  --keystore-password "passw0rd" \
  --alias "vault" \
  --vault-block "vb" \
  --attribute "dbpw" \
  --sec-attr "RealDBPassword!" \
  --enc-dir "/app/was/JBoss/vault" \
  --iteration "44" \
  --salt "JBo72ssv"
중요 (Result Check):
명령어 실행 결과에서 아래 두 가지 값을 반드시 기록해 두어야 합니다.
1. Vault Configuration: KEYSTORE_PASSWORD 값 (예: MASK-1234abcd...)
2. Vault Block: 실제 사용될 암호화 문자열 (예: ${VAULT::vb::dbpw::1})

4. JBoss Vault 구성 등록 (Configuration)

JBoss가 위에서 만든 KeyStore를 인식할 수 있도록 설정합니다. XML을 직접 수정하거나 CLI를 사용할 수 있습니다.

Standalone Mode (standalone.xml)

<vault> 섹션을 추가합니다. (일반적으로 <extensions> 뒤쪽)

<vault>
    <vault-option name="KEYSTORE_URL" value="D:\app\was\JBoss\vault\vault.keystore"/>
    <vault-option name="KEYSTORE_PASSWORD" value="MASK-xxxx"/> <!-- Vault 실행 결과값 -->
    <vault-option name="KEYSTORE_ALIAS" value="vault"/>
    <vault-option name="SALT" value="JBo72ssv"/>
    <vault-option name="ITERATION_COUNT" value="44"/>
    <vault-option name="ENC_FILE_DIR" value="D:\app\was\JBoss\vault\"/>
</vault>

Domain Mode (host.xml 권장)

도메인 모드에서는 물리적 파일 경로(KeyStore 위치)가 서버마다 다를 수 있으므로, 각 서버의 host.xml에 설정을 추가하는 것이 일반적입니다.

<!-- host.xml의 <management> 또는 <vault> 영역 -->
<vault>
    <vault-option name="KEYSTORE_URL" value="/app/was/JBoss/vault/vault.keystore"/>
    <vault-option name="KEYSTORE_PASSWORD" value="MASK-xxxx"/>
    <vault-option name="KEYSTORE_ALIAS" value="vault"/>
    <vault-option name="SALT" value="JBo72ssv"/>
    <vault-option name="ITERATION_COUNT" value="44"/>
    <vault-option name="ENC_FILE_DIR" value="/app/was/JBoss/vault/"/>
</vault>

5. 데이터소스 비밀번호 적용

마지막으로 데이터소스 설정 파일(standalone.xml 또는 domain.xml)에서 평문 비밀번호를 Vault 문자열로 교체합니다.

<datasource jndi-name="java:jboss/datasources/ExampleDS" ...>
    ...
    <security>
        <user-name>dbuser</user-name>
        <!-- 암호화된 문자열 적용 -->
        <password>${VAULT::vb::dbpw::1}</password>
    </security>
</datasource>

Next Step:
설정이 완료되었다면 JBoss를 재기동하고 관리 콘솔에서 Test Connection을 수행하여 DB 연결이 정상적으로 이루어지는지 확인하십시오.

Open Stream →
#EAP6

[JBoss EAP 6] 도메인 모드 보안 강화: Vault를 이용한 Datasource 패스워드 암호화 및 무중단 적용 전략

JBoss EAP 6.4 도메인 모드(Domain Mode)에서 평문으로 저장된 데이터소스 비밀번호를 보호하기 위해 Vault를 구성하는 방법을 정리합니다. host.xmldomain.xml의 설정 분리 원칙을 이해하고, 이중화된 환경에서 서비스 중단 없이 적용하는 순차적 배포 전략을 다룹니다.

0. 배경 및 아키텍처 (Context)

보안 감사 요건 충족을 위해 DB 패스워드 암호화는 필수입니다. 도메인 모드에서는 다음과 같은 설정 분리가 필요합니다.

  • host.xml: 물리적인 Keystore 파일의 위치와 암호화 키 해독 설정 (Vault 선언)
  • domain.xml: 실제 암호화된 문자열을 사용하는 데이터소스 설정 (Vault 참조)

1. Vault 환경 준비 (Keystore 생성)

암호화 키를 저장할 Java Keystore를 생성합니다. JDK의 keytool을 사용합니다.

# Keystore 생성 (알고리즘: DESede 또는 AES)
keytool -genkey -alias vault -keyalg DESede -keystore vault.keystore -keysize 168 -storepass [키스토어_비밀번호] -validity 3650
Tip: 생성된 vault.keystore 파일은 마스터(Master)와 슬레이브(Slave) 서버 모두 동일한 경로(예: EAP_HOME/vault/)에 복사해 두어야 합니다.

2. Vault 초기화 및 비밀번호 암호화

JBoss에서 제공하는 스크립트를 사용하여 Vault를 초기화하고, 실제 DB 패스워드를 암호화된 문자열로 변환합니다.

대화형 모드 실행 (Interactive)

$JBOSS_HOME/bin/vault.sh

위 명령 실행 후 옵션 0 (Store a secured attribute)을 선택하여 진행하거나, 아래와 같이 CLI 파라미터로 한 번에 실행할 수도 있습니다.

# CLI 파라미터 예시
$JBOSS_HOME/bin/vault.sh \
--keystore vault.keystore \
--keystore-password [키스토어_비밀번호] \
--alias vault \
--vault-block ds_vault \
--attribute db_password \
--sec-attr [실제_DB_비밀번호] \
--enc-dir /path/to/vault/ \
--iteration 120 \
--salt 1234abcd

결과 확인: 출력되는 VAULT::ds_vault::db_password::1 형태의 문자열과, 화면에 표시되는 XML 설정 블록을 복사해 둡니다.


3. host.xml 설정 (Vault 선언)

물리적인 파일 경로를 인식해야 하는 모든 호스트 컨트롤러(Master, Slave)host.xml 파일을 수정합니다.

<!-- host.xml의 <management> 섹션 내, 또는 <vault> 섹션 -->
<vault>
    <vault-option name="KEYSTORE_URL" value="/path/to/vault/vault.keystore"/>
    <vault-option name="KEYSTORE_PASSWORD" value="MASK-..."/> <!-- 마스킹된 비밀번호 -->
    <vault-option name="KEYSTORE_ALIAS" value="vault"/>
    <vault-option name="SALT" value="1234abcd"/>
    <vault-option name="ITERATION_COUNT" value="120"/>
    <vault-option name="ENC_FILE_DIR" value="/path/to/vault/" />
</vault>

4. domain.xml 설정 (Datasource 적용)

이제 도메인 컨트롤러의 domain.xml에서 데이터소스 비밀번호 부분을 위에서 생성한 Vault 문자열로 대체합니다.

<datasource ...>
    <security>
        <user-name>dbuser</user-name>
        <password>${VAULT::ds_vault::db_password::1}</password>
    </security>
</datasource>

5. 운영 환경 적용 전략 (Deployment Strategy)

이중화(HA)된 운영 환경에서 서비스 중단을 방지하기 위해, host.xml 설정과 domain.xml 설정을 분리하여 적용하는 전략이 필요합니다.

Scenario A: 무중단 순차 적용 (Rolling Update)

Host Controller(HC) 설정인 host.xml은 재기동이 필요하지만, domain.xml 변경은 리로드(Reload)로 반영될 수 있음을 이용합니다.

  1. Slave 서버(Server2) 작업:
    • Slave HC 중지
    • Slave host.xml에 Vault 설정 추가 및 vault.keystore 파일 배포
    • Slave HC 재기동 (이때 Server2 인스턴스들도 재기동됨)
  2. Master 서버(Server1) 작업:
    • Master HC 중지 (도메인 컨트롤러 중지)
    • Master host.xml에 Vault 설정 추가 및 vault.keystore 파일 배포
    • Master HC 재기동
  3. Datasource 변경:
    • Master가 기동된 상태에서 domain.xml의 데이터소스 패스워드를 ${VAULT::...}로 변경
    • JBoss CLI 또는 콘솔에서 Datasource Disable/Enable 수행 (또는 reload)

Scenario B: 전체 중단 후 적용 (Cold Restart)

가장 안전하고 확실한 방법입니다. 유지보수 시간(Maintenance Window)이 확보되었을 때 권장합니다.

  1. 모든 JBoss 프로세스(Master/Slave) 종료
  2. 모든 서버의 host.xml 수정 및 키스토어 배포
  3. Master 서버의 domain.xml 수정
  4. Master 기동 → Slave 기동 순서로 전체 재시작

6. 검증 (Verification)

  • 서버 기동 로그(server.log)에 Vault 관련 에러(PBOX000...)가 없는지 확인합니다.
  • 관리 콘솔에서 Datasource의 Test Connection을 수행하여 DB 연결이 정상적인지 확인합니다.
Open Stream →
#EAP7

[JBoss EAP 7] 보안 헤더 숨기기: Server 및 X-Powered-By 정보 노출 방지 (Undertow Filter 설정)

JBoss EAP 7.4 (Undertow)의 HTTP 응답 헤더에 노출되는 서버 버전 정보(Server: JBoss-EAP/7, X-Powered-By: JSP/2.3)를 제거하거나 변경하여 보안성을 강화하는 방법을 정리합니다. CLI 명령어를 이용한 JSP 설정 변경과 필터(Filter) 적용 방법을 다룹니다.

1. 문제 현상 (Issue)

기본 설정 상태에서 JBoss EAP 7.4는 응답 헤더에 구체적인 미들웨어 정보를 노출합니다. 이는 공격자에게 서버 정보를 제공하는 단서가 되므로 보안 취약점으로 분류됩니다.

노출되는 헤더 예시

HTTP/1.1 200 OK
X-Powered-By: Undertow/1
X-Powered-By: JSP/2.3
Server: JBoss-EAP/7
...

2. 해결 방법 (Resolution Plan)

조치는 크게 두 단계로 나뉩니다. ① JSP 엔진이 자동으로 붙이는 헤더 비활성화, ② Undertow 필터를 사용하여 Server 헤더 덮어쓰기입니다.

Step 1: X-Powered-By (JSP) 비활성화

서블릿 컨테이너 설정에서 JSP 엔진이 해당 헤더를 생성하지 못하도록 설정합니다.

[JBoss CLI 명령어]

# JSP 설정의 x-powered-by 속성을 false로 변경
/subsystem=undertow/servlet-container=default/setting=jsp:write-attribute(name=x-powered-by,value=false)

# 설정 적용을 위한 리로드 (필요시)
reload
확인: 관리 콘솔에서도 Configuration > Subsystems > Undertow > Servlet Container > JSP 항목에서 X-Powered-By 체크박스가 해제된 것을 확인할 수 있습니다.

Step 2: Server 헤더 변경/삭제 (Undertow Filter)

Server 헤더는 엔진 레벨에서 붙는 경우가 많아 아예 삭제가 어렵다면, 필터(Filter)를 통해 무의미한 값으로 덮어쓰는(Override) 방식을 사용합니다.

[JBoss CLI 명령어]

# 1. 헤더 변경용 필터 생성 (이름: server-header, 값: "Apache" 또는 빈 값)
/subsystem=undertow/configuration=filter/response-header=server-header:add(header-name="Server", header-value="Apache")

# 2. X-Powered-By (Undertow) 헤더 제거 필터 생성 (필요 시)
/subsystem=undertow/configuration=filter/response-header=x-powered-by-header:add(header-name="X-Powered-By", header-value="Unknown")

# 3. 생성한 필터를 기본 호스트(default-host)에 적용
/subsystem=undertow/server=default-server/host=default-host/filter-ref=server-header:add
/subsystem=undertow/server=default-server/host=default-host/filter-ref=x-powered-by-header:add
Tip: header-value에 빈 값("")을 넣거나 일반적인 웹 서버 이름("Webserver")을 넣어 공격자에게 혼동을 줄 수 있습니다.

3. 조치 결과 확인 (Verification)

설정 적용 후 curl 명령어나 브라우저 개발자 도구를 통해 응답 헤더가 변경되었는지 확인합니다.

변경 전후 비교

헤더(Header) 변경 전 (Before) 변경 후 (After)
Server JBoss-EAP/7 Apache (설정한 값)
X-Powered-By JSP/2.3, Undertow/1 (삭제됨) 또는 Unknown
Security Header Verification

[그림] 조치 후 헤더 정보 노출 테스트 결과

Open Stream →
#EAP7

[JBoss EAP 7] Datasource 패스워드 암호화 가이드: Picketbox Security Domain 설정

보안 컴플라이언스 준수를 위해 JBoss EAP 7의 standalone.xml 또는 domain.xml 파일 내에 저장되는 DB 패스워드를 암호화하는 방법을 정리합니다. org.picketbox 모듈을 이용하여 암호화된 문자열을 생성하고, Security Domain을 통해 데이터소스와 연동합니다.

0. 배경 및 준비 (Context)

JBoss 설정 파일에 비밀번호를 평문으로 저장하면 보안 감사 시 지적 대상이 됩니다. 이를 해결하기 위해 JBoss는 Security Domain을 통해 인증 과정을 위임하는 방식을 제공합니다.

Test Environment

  • OS: CentOS 7.2
  • WAS: JBoss EAP 7.2
  • JDK: 1.8

1. 비밀번호 암호화 문자열 생성 (Encryption)

가장 먼저 실제 DB 패스워드를 암호화된 문자열로 변환해야 합니다. JBoss 내부 모듈인 picketbox를 Java로 실행하여 변환합니다.

암호화 스크립트 (create_encrypt_pw.sh)

JBoss 패치(CP)가 적용되면 .overlays 디렉토리에 라이브러리가 변경될 수 있습니다. 아래 스크립트는 패치 여부를 자동으로 감지하여 적절한 jar 파일을 찾아 실행합니다.

#!/bin/sh

# 1. 환경 변수 설정 (사용자 환경에 맞게 수정 필수)
export JAVA_HOME="/SW/was/java1.8"
export PATH="$JAVA_HOME/bin:$PATH"
JBOSS_HOME="/SW/was/JBoss7.2"

# 2. 라이브러리 경로 탐색 (Overlay 지원)
OVERLAY_DIRECTORY="$JBOSS_HOME/modules/system/layers/base/.overlays"
SEARCH_DIRECTORY="$JBOSS_HOME/modules/system/layers/base/org/picketbox/main"

if [ -d "$OVERLAY_DIRECTORY" ]; then
    # 최신 패치 디렉토리 확인
    PATCH_SUBDIRECTORY=$(ls -dt $OVERLAY_DIRECTORY/* | grep "CP" | head -n 1)
    if [ -n "$PATCH_SUBDIRECTORY" ]; then
        echo "Info: Patch directory detected: $PATCH_SUBDIRECTORY"
        SEARCH_DIRECTORY="$PATCH_SUBDIRECTORY/org/picketbox/main"
    fi
fi

# 3. Classpath 설정
export CLASSPATH=$(find "$SEARCH_DIRECTORY" -name "*.jar" -print | tr '\n' ':')$CLASSPATH

# 4. 암호화 실행
echo ""
read -p "Enter Database Password : " PASSWORD
echo ""
echo "####################################################"
java org.picketbox.datasource.security.SecureIdentityLoginModule "$PASSWORD"
echo "####################################################"
echo ""

실행 결과 예시

Encoded password: 9fdd42c2a7390d3

출력된 Encoded password 값을 복사해 둡니다.


2. Security Domain 설정 (standalone.xml)

생성한 암호화 패스워드를 사용하는 보안 도메인을 정의합니다. security 서브시스템 내에 작성합니다.

설정 내용

<subsystem xmlns="urn:jboss:domain:security:2.0">
    <security-domains>
        
        <security-domain name="encryptedSecurityDB" cache-type="default">
            <authentication>
                <login-module code="org.picketbox.datasource.security.SecureIdentityLoginModule" flag="required">
                    <module-option name="username" value="sa"/>
                    <module-option name="password" value="9fdd42c2a7390d3"/> <!-- 암호화된 값 -->
                    <module-option name="managedConnectionFactoryName" value="jboss.jca:service=LocalTxCM"/>
                </login-module>
            </authentication>
        </security-domain>
        
    </security-domains>
</subsystem>
옵션 설명:
  • username: DB 접속 계정 ID (평문)
  • password: 위에서 생성한 암호화된 패스워드
  • managedConnectionFactoryName: jboss.jca:service=LocalTxCM (고정값 사용)

3. Datasource 연동 설정

이제 데이터소스가 평문 비밀번호 대신 위에서 만든 Security Domain을 바라보도록 수정합니다.

수정 전 (Before)

<datasource ...>
    ...
    <security>
        <user-name>sa</user-name>
        <password>admin1234</password>
    </security>
</datasource>

수정 후 (After)

user-namepassword 태그를 삭제하고 security-domain 태그를 추가합니다.

<datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
    <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
    <driver>h2</driver>
    
    <security>
        <security-domain>encryptedSecurityDB</security-domain>
    </security>
</datasource>

4. 검증 (Verification)

  1. 설정 저장 후 JBoss 서버를 재기동(Reload)합니다.
  2. 관리 콘솔 또는 CLI에서 Test Connection을 수행하여 연결 성공 여부를 확인합니다.
  3. 연결 성공 시, 설정 파일에 비밀번호 평문이 남아있지 않은지 재확인합니다.

Next Step:
만약 비밀번호 뿐만 아니라 키스토어 패스워드 등 JBoss 설정 전반의 민감 정보를 보호해야 한다면, Vault(볼트) 구성을 추가로 검토해 보십시오.

Open Stream →
#EAP7

[JBoss EAP 7] Windows 환경 도메인 모드(Domain Mode) 구축: Master/Slave 구성 및 CLI 제어

JBoss EAP 7.2를 도메인 모드로 구성하여 중앙 집중식 관리 환경을 구축합니다. Windows Server 환경에서 마스터(Master)와 슬레이브(Slave) 호스트를 설정하고, add-user를 통해 보안 인증(Secret Value)을 처리하는 과정, 그리고 CLI를 이용한 제어 방법을 다룹니다.

0. 배경 지식 (Context)

도메인 모드는 Domain Controller(Master)가 전체 정책을 관리하고, Host Controller(Slave)들이 실제 서버 인스턴스를 구동하는 구조입니다.

  • Master: 설정 및 배포 중앙 관리 (서버 인스턴스를 직접 띄우지 않는 것을 권장)
  • Slave: 실제 애플리케이션이 구동되는 서버 그룹 관리

Test Environment

  • OS: Windows NT (10/Server)
  • Version: JBoss EAP 7.2
  • Topology: One-Box 구성 (하나의 서버에 Master/Slave 디렉토리 분리)

1. 관리자 계정 생성 및 인증 토큰 확보

도메인 컨트롤러(Master)와 호스트 컨트롤러(Slave) 간의 통신을 위해서는 보안 인증이 필요합니다. add-user.bat를 통해 계정을 생성하고 Secret Value를 확보해야 합니다.

실행 절차

F:\app\Redhat\JBoss7.2\bin> add-user.bat

# 1. 관리자 계정 선택
What type of user do you wish to add?
 a) Management User (mgmt-users.properties)
 b) Application User (application-users.properties)
(a): a

# 2. 계정 정보 입력 (Username: admin / Password 설정)
# ... (중략) ...

# 3. 프로세스 간 연결 승인 (중요!)
Is this new user going to be used for one AS process to connect to another AS process?
e.g. for a slave host controller connecting to the master ...
yes/no? yes

# 4. 결과값 복사
To represent the user add the following to the server-identities definition
Check Point: 마지막에 출력된 <secret value="..." /> 문자열을 반드시 복사해 두십시오. Slave 설정 시 사용됩니다.

2. 설정 파일 수정 (Configuration)

Master와 Slave 각각의 host.xml 파일을 수정하여 역할을 정의합니다.

1) Master 설정 (host-master.xml)

자신이 도메인 컨트롤러임을 명시합니다.

<host xmlns="urn:jboss:domain:8.0" name="test-master">
    
    <domain-controller>
       <local/>
    </domain-controller>
    ...
</host>

2) Slave 설정 (host-slave.xml)

Master에 연결하기 위한 인증 정보와 고유한 호스트 이름을 설정합니다. 한 장비에서 띄울 경우 포트 충돌 방지를 위해 관리 포트를 변경해야 합니다.

<host xmlns="urn:jboss:domain:8.0" name="slave-node01">

    <server-identities>
        <secret value="YWRtaW4xMiMk" />
    </server-identities>

    <domain-controller>
        <remote security-realm="ManagementRealm">
            <discovery-options>
                <static-discovery name="primary" protocol="${jboss.domain.master.protocol:remote}" host="${jboss.domain.master.address}" port="${jboss.domain.master.port:9990}"/>
            </discovery-options>
        </remote>
    </domain-controller>

    <management-interfaces>
        <http-interface security-realm="ManagementRealm">
            <http-upgrade enabled="true"/>
            <socket interface="management" port="${jboss.management.http.port:19990}"/>
        </http-interface>
    </management-interfaces>
</host>

3. 도메인 기동 (Start Scripts)

디렉토리(domain/base/dir)를 분리하여 운영하는 환경을 가정한 기동 스크립트입니다.

Master 기동

F:\app\Redhat\JBoss7.2\bin\domain.bat ^
 -Djboss.domain.base.dir="F:\app\Redhat\JBoss7.2\master" ^
 -b=192.168.0.6 ^
 -bmanagement=192.168.0.6 ^
 --host-config=host-master.xml

Slave 기동 (Node 01 & 02)

Slave는 --master-address 옵션으로 Master를 바라보며, -Djboss.socket.binding.port-offset으로 서비스 포트 충돌을 방지합니다.

:: Slave Node 01 (Port Offset: 1000)
F:\app\Redhat\JBoss7.2\bin\domain.bat ^
 -Djboss.domain.base.dir="F:\app\Redhat\JBoss7.2\node01" ^
 -b=192.168.0.6 ^
 -bmanagement=192.168.0.6 ^
 --host-config=host-slave.xml ^
 --master-port=9990 ^
 --master-address=192.168.0.6 ^
 -Djboss.socket.binding.port-offset=1000

:: Slave Node 02 (Port Offset: 2000)
F:\app\Redhat\JBoss7.2\bin\domain.bat ^
 -Djboss.domain.base.dir="F:\app\Redhat\JBoss7.2\node02" ^
 -b=192.168.0.6 ^
 -bmanagement=192.168.0.6 ^
 --host-config=host-slave.xml ^
 --master-port=9990 ^
 --master-address=192.168.0.6 ^
 -Djboss.socket.binding.port-offset=2000

4. CLI를 이용한 서버 제어 (Management)

도메인 모드에서는 jboss-cli를 통해 특정 호스트의 특정 서버 인스턴스만 제어할 수 있습니다.

기본 구문

/host=[HOST_NAME]/server-config=[SERVER_NAME]:[start|stop|restart]

실행 예시

:: 접속 (Master Controller IP로 접속)
F:\app\Redhat\JBoss7.2\bin> jboss-cli.bat --connect controller=192.168.0.6:9990

:: 특정 서버(test01) 정지
[domain@192.168.0.6:9990 /] /host=slave-node01/server-config=test01:stop
{
    "outcome" => "success",
    "result" => "STOPPING"
}

:: 특정 서버(test01) 기동
[domain@192.168.0.6:9990 /] /host=slave-node01/server-config=test01:start
{
    "outcome" => "success",
    "result" => "STARTING"
}

Next Step:
구성이 완료되었다면 관리 콘솔(http://192.168.0.6:9990)에 접속하여 Runtime 탭에서 Topology가 정상적으로 인식되는지 확인하십시오.

Open Stream →
#EAP7

[JBoss EAP 7] MS SQL Server Non-XA 데이터소스 연결 오류: connection-url 무시 현상 해결

JBoss EAP 7에서 MS SQL Server용 Non-XA Datasource를 설정할 때, <datasource-class> 태그를 사용하면 <connection-url> 설정이 무시되어 "Connection refused" 에러가 발생하는 현상을 해결합니다. 올바른 설정 방법은 무엇인지 정리합니다.

1. 문제 현상 (Issue)

MS SQL Server와 연결하기 위해 데이터소스를 설정하고 테스트 연결을 시도했으나, 아래와 같은 Connection refused 에러가 발생하며 실패합니다.

에러 로그

Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: 
The TCP/IP connection to the host localhost, port 1433 has failed. 
Error: "Connection refused. Verify the connection properties. ... Make sure that TCP connections to the port are not blocked by a firewall."

방화벽이나 DB 서버 상태는 정상이지만, JBoss가 localhost:1433(기본값)으로만 접속을 시도하거나 URL 정보를 전혀 읽지 못하는 상황입니다.


2. 원인 분석 (Root Cause)

이 문제는 JBoss의 데이터소스 설정 우선순위 메커니즘 때문에 발생합니다.

  • Non-XA 환경의 특성: JDBC 4 표준을 따르는 드라이버를 사용할 때, 일반적으로 java.sql.Driver 메커니즘(URL 방식)을 사용합니다.
  • 충돌 발생: 설정 파일(standalone.xml)에 <datasource-class>가 명시되면, JBoss는 이를 우선시하여 javax.sql.DataSource 구현체를 사용하려고 시도합니다.
  • 결과: 이 과정에서 <connection-url> 속성은 무시(Ignored)됩니다. 결과적으로 JDBC URL 정보가 전달되지 않아 연결에 실패하게 됩니다.

3. 해결 방법 (Resolution)

Non-XA 데이터소스 설정에서는 datasource-class를 제거하고, driver-classconnection-url 조합을 사용해야 합니다.

설정 파일 수정 (standalone.xml)

<datasource-class> 태그가 있는 라인을 삭제하십시오.

<datasource jndi-name="java:/mssql" pool-name="mssqljdbc" statistics-enabled="true">
    
    <connection-url>jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ucpost</connection-url>
    <driver-class>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver-class>
    
    <driver>sqlserver</driver>
    ...
</datasource>

4. 적용 및 검증 (Verification)

  1. 설정 파일 저장 후 JBoss를 재기동(Reload)합니다.
  2. 관리 콘솔 또는 CLI에서 데이터소스 연결 테스트(Test Connection)를 수행합니다.
  3. 정상적으로 Success 메시지가 뜨는지 확인합니다.
Tip: 만약 XA Datasource(분산 트랜잭션용)를 설정하는 경우에는 반대로 xa-datasource-class 설정이 필수적이며 URL 방식은 사용되지 않을 수 있습니다. 설정하려는 타입(XA vs Non-XA)을 명확히 구분해야 합니다.
Open Stream →
#EAP7

[JBoss EAP 7] 마이그레이션 이슈 해결: Apache CXF 라이브러리 충돌 (WFLYWS0059)

JBoss EAP 6.4에서 7.x로 마이그레이션 시, 애플리케이션에 포함된 Apache CXF 라이브러리와 JBoss 내부의 WebServices 서브시스템이 충돌하여 배포가 실패하는 현상(WFLYWS0059)을 해결합니다. jboss-deployment-structure.xml을 통한 모듈 제외(Exclude) 설정을 다룹니다.

1. 문제 현상 및 로그 분석 (Issue)

기존 EAP 6에서는 잘 돌던 애플리케이션이 EAP 7 배포 시 PARSE 단계에서 실패하며 아래와 같은 에러를 뱉어냅니다.

에러 로그

WFLYSRV0153: Failed to process phase PARSE of deployment "sso.war"
Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: 
WFLYWS0059: Apache CXF library (cxf-api-2.7.8.jar) detected in ws endpoint deployment; 
either provide a proper deployment replacing embedded libraries with container module dependencies 
or disable the webservices subsystem for the current deployment adding a proper jboss-deployment-structure.xml descriptor to it.

원인 분석

  • JBoss EAP 7: 기본적으로 최신 Apache CXF 기반의 WebServices 서브시스템을 로드합니다.
  • 애플리케이션: WEB-INF/lib 안에 자체적인 CXF 라이브러리(예: cxf-api-2.7.8.jar)를 포함하고 있습니다.
  • 충돌: JBoss는 애플리케이션이 자체 라이브러리 대신 컨테이너가 제공하는 모듈을 사용하길 권장하며, 중복이 감지되면 배포를 중단시킵니다.

2. 해결 방법 (Resolution)

애플리케이션이 JBoss의 WebServices 기능을 사용하지 않고, "내가 가진 라이브러리를 쓰겠다"고 선언해야 합니다. 이를 위해 jboss-deployment-structure.xml 파일을 생성하여 컨테이너의 특정 서브시스템을 비활성화합니다.

설정 파일 위치

  • WAR 파일: WEB-INF/jboss-deployment-structure.xml
  • EAR 파일: META-INF/jboss-deployment-structure.xml

작성 내용

JBoss의 webservicesjaxrs 서브시스템을 제외(exclude)하고, 필요한 기본 API만 의존성(dependencies)으로 추가합니다.

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
    <deployment>
        
        <!-- 1. JBoss 내부 서브시스템 비활성화 -->
        <exclude-subsystems>
            <!-- JBoss의 CXF 모듈이 로드되지 않도록 차단 -->
            <subsystem name="webservices" />
            <!-- RESTful 서비스 충돌 방지 (필요 시) -->
            <subsystem name="jaxrs" />
        </exclude-subsystems>
        
        <!-- 2. 필수 API 의존성 추가 -->
        <!-- 서브시스템은 뺐지만, 기본적인 Java EE API는 필요하므로 명시적 로드 -->
        <dependencies>
            <module name="javax.xml.ws.api"/>
            <module name="javax.jws.api"/>
        </dependencies>
        
    </deployment>
</jboss-deployment-structure>

3. 적용 결과 및 주의사항

  • 결과: 위 파일을 추가하고 재배포하면, JBoss는 해당 애플리케이션에 대해 WebServices 서브시스템 초기화를 건너뛰고 WEB-INF/lib 내의 jar 파일들을 우선적으로 로딩합니다.
  • 주의: 이 방식을 사용하면 JBoss 관리 콘솔에서 제공하는 웹 서비스 모니터링이나 관리 기능을 해당 애플리케이션에 대해서는 사용할 수 없게 됩니다. (애플리케이션 자체 프레임워크인 Spring-CXF 등이 전적으로 처리함)
Open Stream →
#EAP7

[JBoss EAP 7.2] Windows Service 등록 및 멀티 인스턴스 구성 가이드 (Jsvc, Port Offset)

JBoss EAP 7.2를 Windows 서비스로 등록하여 시스템 부팅 시 자동으로 실행되도록 설정합니다. Apache Jsvc를 활용한 서비스 등록 방법, 멀티 인스턴스 구성을 위한 포트 오프셋(Port Offset) 설정, 그리고 특수문자 패스워드 처리 팁을 정리합니다.

0. 사전 준비 (Prerequisites)

JBoss EAP 7부터는 서비스 등록을 위해 JBoss Core Services (JBCS) - Apache Jsvc 패키지가 필요할 수 있습니다. Red Hat 포털에서 해당 바이너리를 다운로드하여 준비합니다.

필수 다운로드 및 환경 변수

  • JBoss EAP 7.2: 설치 파일 압축 해제
  • Apache Jsvc: Windows용 바이너리 (sbin 폴더 내 prunsrv.exe 등 포함)
  • 환경 변수:
    • JAVA_HOME: JDK 설치 경로
    • NOPAUSE=1: 서비스 종료 시 배치 파일이 멈추지 않도록 필수 설정

1. 단일 인스턴스 서비스 등록

기본적으로 제공되는 service.bat 스크립트를 사용하여 서비스를 등록합니다.

등록 명령어

아래 명령어를 관리자 권한 CMD 창에서 실행합니다. 로그 경로(/logpath)는 미리 생성되어 있어야 합니다.

:: JBoss bin 디렉토리로 이동
cd %JBOSS_HOME%\bin

:: 서비스 등록 실행
service.bat install /name "JBoss7-Server01" ^
 /controller "localhost:9990" ^
 /config "standalone-ha.xml" ^
 /jbossuser "admin" ^
 /jbosspass "admin1@34" ^
 /logpath "E:\app\Redhat\waslog\testsvr01"
주의 (Password Special Characters):
비밀번호에 &, <, >, | 등의 특수문자가 포함된 경우 CMD 창에서 오류가 발생할 수 있습니다. 가능한 경우 특수문자를 피하거나, 쌍따옴표(")로 감싸고 이스케이프 문자(^)를 사용하는 등 주의가 필요합니다.

2. 멀티 인스턴스(Multi-Instance) 구성

하나의 장비에 여러 개의 JBoss 서비스를 등록할 때는 서비스 이름, 포트, 로그 경로가 겹치지 않아야 합니다.

Step 1: Port Offset 설정 (XML 수정)

service.bat의 파라미터로 포트 오프셋을 넘기는 것이 불안정할 수 있으므로, 설정 파일(standalone.xml) 자체를 수정하는 것을 권장합니다.

<socket-binding-group name="standard-sockets" default-interface="public" 
    port-offset="${jboss.socket.binding.port-offset:100}">
    </socket-binding-group>

Step 2: Jsvc 경로 수정 (필요 시)

멀티 인스턴스 환경에서 각 서버별로 다른 Jsvc 바이너리를 사용해야 하거나 경로가 특수한 경우, service.bat 파일을 열어 PRUNSRV 경로를 수동으로 지정해야 할 수 있습니다.

rem service.bat 파일 편집
set PRUNSRV=

rem 커스텀 경로 우선 확인 로직 예시
if exist "%JBOSS_HOME%\..\test01-jbcs-jsvc-1.1\sbin\prunsrv.exe" (
  set PRUNSRV="%JBOSS_HOME%\..\test01-jbcs-jsvc-1.1\sbin\prunsrv.exe"
) else if exist "%JBOSS_HOME%\bin\prunsrv.exe" (
  set PRUNSRV="%JBOSS_HOME%\bin\prunsrv.exe"
) else (
  echo Please install native utilities into expected location...
  goto cmdEnd
)

Step 3: 추가 인스턴스 등록

서비스 이름과 컨트롤러 포트, 로그 경로를 변경하여 등록합니다.

service.bat install /name "JBoss7-Server02" ^
 /controller "localhost:10090" ^
 /config "standalone-ha.xml" ^
 /jbossuser "admin" ^
 /jbosspass "admin1@34" ^
 /logpath "E:\app\Redhat\waslog\testsvr02"

3. 서비스 제어 및 삭제

등록된 서비스는 Windows 서비스 관리자(services.msc) 또는 명령어로 제어할 수 있습니다.

서비스 삭제 (Uninstall)

설정을 변경하거나 재등록할 경우 기존 서비스를 삭제해야 합니다. /name 옵션에 등록했던 서비스명을 정확히 입력합니다.

:: 서비스 중지
sc stop JBoss7-Server01

:: 서비스 삭제 (service.bat 이용)
service.bat uninstall /name "JBoss7-Server01"

4. 검증 (Verification)

  1. 서비스 실행: net start JBoss7-Server01
  2. 포트 확인: netstat -an | findstr "9990" (또는 오프셋이 적용된 포트)
  3. 로그 확인: 지정한 /logpath 경로에 로그 파일이 생성되는지 확인합니다.
Open Stream →
#JBoss

[JBoss EAP 7] JSESSIONID 형식 변경 이슈 분석 및 jvmRoute(Instance-ID) 설정 가이드

JBoss EAP 7 도입 시 JSESSIONID 뒤에 예상치 못한 문자열(서버명, 그룹명 등)이 붙거나 길이가 늘어나는 현상을 분석합니다. 이는 Undertow 엔진의 JvmRouteHandler 동작 방식 때문이며, 이를 제어하기 위한 설정 방법을 정리합니다.

1. 이슈 현상 및 원인 분석 (Context)

EAP 6와 EAP 7은 세션 ID를 생성하고 관리하는 방식에 차이가 있습니다. 특히 클러스터링 환경에서 Sticky Session(세션 고정)을 위해 ID 뒤에 붙이는 식별자(Route)의 기본 동작이 다릅니다.

버전별 차이점

구분 JBoss EAP 6.x (JBossWeb) JBoss EAP 7.x (Undertow)
Engine Apache Tomcat Fork Undertow
Format [ID].[jvmRoute] [ID].[instance-id]
Default 설정 없으면 ID만 생성하거나 Hostname 부착 강제로 jboss.node.name 부착

기술적 원인 (Undertow JvmRouteHandler)

EAP 7의 웹 엔진인 Undertow는 io.undertow.server.JvmRouteHandler를 통해 세션 ID를 처리합니다. 이 핸들러는 클러스터링 설정 여부와 관계없이, 설정된 instance-id가 있다면 무조건 세션 ID 뒤에 붙이도록 설계되어 있습니다. 또한, 이 값은 null이거나 비활성화(disable)할 수 없으며 기본적으로 노드 이름을 따라갑니다.


2. 해결 및 설정 방법 (Configuration)

JSESSIONID 뒤에 붙는 값을 제어하기 위해서는 undertow 서브시스템의 instance-id 속성을 명시적으로 변경해야 합니다.

설정 파일 수정 (standalone.xml / domain.xml)

Undertow 서브시스템 설정에서 instance-id 값을 원하는 식별자(기존 jvmRoute와 동일한 역할)로 지정합니다.

<subsystem xmlns="urn:jboss:domain:undertow:3.1">
    <buffer-cache name="default"/>
    <server name="default-server">
        <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
        <ajp-listener name="ajp" socket-binding="ajp"/>
        <host name="default-host" alias="localhost">
            ...
        </host>
    </server>
    
    <servlet-container name="default" default-session-timeout="30" instance-id="${jboss.node.name}" />
    
</subsystem>

CLI를 이용한 변경

운영 중인 환경에서 값을 변경하려면 관리 CLI를 사용하는 것이 안전합니다.

# instance-id를 'node1'으로 변경하는 예시
/subsystem=undertow/servlet-container=default:write-attribute(name=instance-id, value="node1")

# 설정 적용을 위해 리로드 필요
reload
주의 (Warning):
instance-id를 변경하면 기존에 발급된 세션 ID와 매핑이 달라지므로, 기존 사용자들의 세션이 끊길(Invalidate) 수 있습니다. 서비스 점검 시간에 수행하십시오.

3. 검증 (Verification)

설정 변경 후 애플리케이션을 호출하여 쿠키 값을 확인합니다.

개발자 도구 확인

  1. 브라우저 F12 (개발자 도구) 실행
  2. Application 탭 > Cookies 선택
  3. JSESSIONID의 값 확인

결과 예시:

  • 변경 전: abcde12345.server-one-instance-group-a (길고 복잡함)
  • 변경 후: abcde12345.node1 (설정한 값으로 깔끔해짐)

Next Step:
만약 앞단의 웹 서버(Apache/IHS)와 mod_cluster 또는 mod_jk로 연동 중이라면, 웹 서버 설정의 jvmRoute 값과 JBoss의 instance-id 값이 정확히 일치해야 스티키 세션(Sticky Session)이 정상 작동합니다. 반드시 양쪽 설정을 맞춰주세요.

Open Stream →
#Error

[JBoss EAP 7] 설치 오류 해결: java.lang.UnsupportedClassVersionError (JDK 버전 호환성)

JBoss EAP 7 설치 또는 기동 중 java.lang.UnsupportedClassVersionError가 발생한다면, 현재 서버에 설정된 Java 버전이 JBoss가 요구하는 최소 사양(JDK 1.8)보다 낮기 때문입니다. 에러 메시지의 major.minor version 숫자를 통해 원인을 분석하는 방법을 알아봅니다.

1. 문제 현상 및 원인 분석

JBoss 설치 스크립트 실행 시 아래와 같은 에러 로그가 출력되며 프로세스가 종료됩니다.

Exception in thread "main" java.lang.UnsupportedClassVersionError: 
com/ibm/websphere/... : Unsupported major.minor version 52.0
    at java.lang.ClassLoader.defineClass1(Native Method)
    ...

원인 (Root Cause)

이 에러는 컴파일된 클래스 파일의 버전(Target JVM)보다 현재 실행 중인 JVM 버전(Runtime)이 낮을 때 발생합니다.

  • JBoss EAP 7.x 요구사항: 최소 JDK 1.8 이상
  • 현재 서버 상황: JDK 1.7 이하가 설치되어 있거나 JAVA_HOME이 구버전을 가리키고 있음

2. 버전 매핑 테이블 (Class File Format)

에러 메시지에 뜨는 숫자(52.0, 51.0 등)는 Java 클래스 파일 포맷의 메이저 버전을 의미합니다. 아래 표를 참고하여 현재 필요한 Java 버전을 확인하십시오.

Java Version (SE) Major Version (Hex) Major Version (Dec)
Java 14 0x3A 58
Java 13 0x39 57
Java 12 0x38 56
Java 11 0x37 55
Java 9 0x35 53
Java 8 0x34 52
Java 7 0x33 51
Java 6 0x32 50
분석 예시:
에러 메시지가 Unsupported major.minor version 52.0이라면, 해당 프로그램은 Java 8로 컴파일되었으므로 서버에도 Java 8 이상이 설치되어야 합니다.

3. 해결 방법 (Solution)

1) 현재 Java 버전 확인

java -version

출력 결과가 1.7.x 이하라면 JDK 업그레이드가 필요합니다.

2) JDK 설치 및 환경 변수 변경

서버에 JDK 1.8 이상을 설치한 후, JBoss가 참조하는 설정 파일에서 JAVA_HOME 경로를 수정해야 합니다.

  • Standalone 모드: [EAP_HOME]/bin/standalone.conf (Windows는 .bat)
  • Domain 모드: [EAP_HOME]/bin/domain.conf (Windows는 .bat)
# standalone.conf 예시
# JAVA_HOME="/usr/lib/jvm/java-1.7.0"  <-- 기존 (주석 처리)
JAVA_HOME="/usr/lib/jvm/java-1.8.0"    <-- 신규 경로로 변경

Next Step:
JDK 버전을 올린 후에는 기존 애플리케이션(WAR/EAR)이 새 Java 버전에서 정상적으로 동작하는지, -Xmx 등 메모리 옵션이 변경된 버전에 맞게 설정되었는지 확인해야 합니다.

Open Stream →
#JBoss

[JBoss EAP 6] 커스텀 기동/정지 스크립트 작성 가이드 (Config 분리 및 JVM 튜닝)

JBoss EAP 6 Standalone 모드의 운영 효율성을 높이기 위해, JVM 옵션과 환경 변수를 별도의 설정 파일(Config Shell)로 분리하고 이를 로드하여 서버를 제어(Start/Stop/Status)하는 커스텀 쉘 스크립트 작성법을 공유합니다.

Test Environment

  • OS: CentOS 7.2
  • Middleware: JBoss EAP 6.4

1. 스크립트 구조 및 전략

유지보수성과 확장성을 위해 스크립트를 두 개의 파일로 분리합니다.

  1. Config Script (config1.sh): JVM 옵션, 경로, IP, 포트 등 변수 정의.
  2. Control Script (jboss_ctl.sh): Config를 로드하여 실제 프로세스를 제어하는 로직.

2. 설정 스크립트 (config1.sh)

서버 인스턴스별 고유한 설정을 이곳에 정의합니다. JAVA_OPTS를 통해 메모리 및 GC 로그 설정을 상세하게 튜닝할 수 있습니다.

#!/bin/sh
DATE=`date +%Y%m%d%H%M%S`

##### 1. Basic Configuration #####
export JBOSS_HOME=/SW/was/JBoss
export SERVER_HOME=/SW/was/JBoss/TEST/TESTServer11
export LOG_PATH=/app/logs/was
export NODE_NAME=TESTServer11
export CONFIG_FILE=standalone-ha.xml

# Network & Port Offset
export SERVER_IP=10.252.16.25
export PORT_OFFSET=750
export MGMT_ADDR=$SERVER_IP

# Controller Port Calculation (Base 9999 + Offset)
let CONTROLLER_PORT=9999+$PORT_OFFSET
export CONTROLLER_PORT

# Admin User (Shutdown용)
export USER=admin

##### 2. JVM Options (Memory & GC) #####
# Heap Memory
export JAVA_OPTS="-server -Xms1024m -Xmx2048m -XX:MaxPermSize=256m"

# GC Logging
export JAVA_OPTS=" $JAVA_OPTS -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails "
export JAVA_OPTS=" $JAVA_OPTS -Xloggc:$LOG_PATH/log/gclog/gc_$DATE.log "

# GC Algorithm (ParallelGC)
export JAVA_OPTS=" $JAVA_OPTS -XX:+UseParallelGC -XX:+ExplicitGCInvokesConcurrent"

# Heap Dump on OOM
export JAVA_OPTS=" $JAVA_OPTS -XX:-HeapDumpOnOutOfMemoryError "
export JAVA_OPTS=" $JAVA_OPTS -XX:HeapDumpPath=$LOG_PATH/heap/$NODE_NAME "

##### 3. System Properties (-D options) #####
export JAVA_OPTS=" $JAVA_OPTS -Djava.net.preferIPv4Stack=true"
export JAVA_OPTS=" $JAVA_OPTS -Dorg.jboss.resolver.warning=true"
export JAVA_OPTS=" $JAVA_OPTS -Djava.awt.headless=true"
export JAVA_OPTS=" $JAVA_OPTS -DjvmRoute=$NODE_NAME"

# JBoss Path & Binding
export JAVA_OPTS=" $JAVA_OPTS -Djboss.server.base.dir=$SERVER_HOME"
export JAVA_OPTS=" $JAVA_OPTS -Djboss.server.log.dir=$LOG_PATH/$NODE_NAME"
export JAVA_OPTS=" $JAVA_OPTS -Djboss.socket.binding.port-offset=$PORT_OFFSET"
export JAVA_OPTS=" $JAVA_OPTS -Djboss.node.name=$NODE_NAME"
export JAVA_OPTS=" $JAVA_OPTS -Djboss.bind.address.management=$MGMT_ADDR"
export JAVA_OPTS=" $JAVA_OPTS -Djboss.bind.address=$SERVER_IP"

# Clustering (Multicast)
export JAVA_OPTS=" $JAVA_OPTS -Djboss.default.jgroups.stack=tcp"
# export JAVA_OPTS=" $JAVA_OPTS -Djboss.default.multicast.address=230.1.0.1"

echo "Configuration Loaded: $NODE_NAME"

3. 제어 스크립트 (jboss_ctl.sh)

실제 기동 및 정지를 담당하는 메인 스크립트입니다. ./config/config1.sh를 로드하여 변수들을 가져옵니다.

#!/bin/sh

# Config 파일 로드 (경로 주의)
. ./config/config1.sh

start(){
    # 프로세스 중복 실행 방지
    PID=`ps -ef | grep java | grep "jboss.node.name=$NODE_NAME " | awk '{print $2}'`
    
    if [ "x$PID" != "x" ]; then
        echo "###############################################"
        echo "ERROR: JBoss SERVER ($NODE_NAME) is already RUNNING (PID=$PID)"
        echo "###############################################"
        exit 1
    fi

    echo "#######################"
    echo "   Starting JBoss EAP  "
    echo "#######################"
    
    # nohup으로 백그라운드 실행, 로그 리다이렉션
    nohup $JBOSS_HOME/bin/standalone.sh --server-config=$CONFIG_FILE >> $LOG_PATH/console.log 2>&1 &

    echo "Starting... Wait for checking status..."
    sleep 5
    status
}

stop(){
    echo "#######################"
    echo "    Stopping JBoss     "
    echo "#######################"
    
    # 보안을 위해 패스워드는 입력받도록 처리 (자동화 시 변수로 대체 가능)
    echo -n "Enter Controller Password: "
    read -s PASSWORD
    echo ""

    # CLI를 이용한 안전한 종료 (Graceful Shutdown)
    $JBOSS_HOME/bin/jboss-cli.sh --connect --controller=$SERVER_IP:$CONTROLLER_PORT --command=:shutdown --user=$USER --password=$PASSWORD
}

status() {
    # 포트 리슨 상태로 구동 여부 확인
    _up=`netstat -an | grep $CONTROLLER_PORT | grep LISTEN | wc -l`
    
    if [ "$_up" -ne 0 ]; then
        PID=`ps -ef | grep java | grep "jboss.node.name=$NODE_NAME " | awk '{print $2}'`
        echo "###############################################"
        echo " JBoss Server is RUNNING !! "
        echo " Node: $NODE_NAME (PID: $PID)"
        echo " Port: $CONTROLLER_PORT (Management)"
        echo "###############################################"
    else
        echo "##################################"
        echo " JBoss Server is STOPPED !! "
        echo " Node: $NODE_NAME "
        echo "##################################"
    fi
}

# 파라미터 처리
case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  status)
    status
    ;;
  restart)
    stop
    sleep 5
    start
    ;;
  *)
    echo "Usage: $0 {start|stop|status|restart}"
    exit 1
esac
exit 0

4. 사용 방법 및 주의사항

사용법

# 실행 권한 부여
chmod +x jboss_ctl.sh

# 기동
./jboss_ctl.sh start

# 상태 확인
./jboss_ctl.sh status

# 정지 (패스워드 입력 필요)
./jboss_ctl.sh stop
Tip: config1.sh 파일 내의 PORT_OFFSET 변수를 활용하면, 하나의 물리 서버에서 포트 충돌 없이 여러 개의 인스턴스를 띄울 수 있습니다. (예: 0, 100, 200...)
Open Stream →
#JBoss

[JBoss EAP 6] CLI 기반 패치 적용(Apply) 및 롤백(Rollback) 완벽 가이드

JBoss EAP 6 환경에서 Management CLI(jboss-cli)를 사용하여 보안 패치나 버그 픽스를 적용(Apply)하고, 문제 발생 시 이전 상태로 되돌리는 롤백(Rollback) 절차를 정리합니다. 패치 이력 관리와 설정 초기화 옵션에 대한 이해가 필수적입니다.

0. 배경 지식 (Context)

JBoss EAP 6의 패치 시스템은 누적(Cumulative) 방식과 단일(One-off) 방식으로 나뉩니다. 패치를 적용하면 내부적으로 .installation 디렉토리에 변경 내역이 저장되며, 이를 통해 언제든 이전 시점으로 복원할 수 있습니다.

Test Environment

  • OS: Windows 10 (Linux 명령어 포함)
  • Middleware: JBoss EAP 6.4
  • Patch File: jboss-eap-6.4.19-patch.zip

1. 패치 적용 (Patch Apply)

패치 파일을 다운로드한 후, JBoss가 가동된 상태(또는 Embed 모드)에서 CLI를 통해 적용합니다.

명령어 구문

# 기본 구문
patch apply [패치파일_경로]

OS별 실행 예시

Linux

$JBOSS_HOME/bin/jboss-cli.sh --connect
[standalone@localhost:9999 /] patch apply /was/img/fix/jboss-eap-6.4.19-patch.zip

Windows

%JBOSS_HOME%\bin\jboss-cli.bat --connect
[standalone@localhost:9999 /] patch apply F:\app\was\jboss-eap-6.4.19-patch.zip
Note: 패치 적용 후에는 변경된 모듈을 로드하기 위해 반드시 서버를 재기동(Restart)해야 합니다.

2. 패치 이력 확인 (Verification)

패치가 정상적으로 적용되었는지, 혹은 롤백을 위해 돌아갈 시점(ID)을 확인해야 합니다.

CLI에서 확인

# 패치 정보 조회
[standalone@localhost:9999 /] patch history

# 상세 정보 조회
[standalone@localhost:9999 /] patch info

파일 시스템에서 확인

JBoss 설치 경로 내의 숨김 폴더를 통해서도 확인 가능합니다.

  • 경로: {JBoss_HOME}/.installation/patches

3. 패치 롤백 (Patch Rollback)

패치 적용 후 애플리케이션에 문제가 생겼다면 즉시 이전 상태로 되돌려야 합니다.

사전 준비: Patch ID 확인

롤백할 대상 ID를 알아야 합니다. patch history 명령어로 가장 최근에 적용된 패치 ID를 확인하십시오.

롤백 명령어

# 구문
patch rollback --patch-id=[PATCH_ID] --reset-configuration=[TRUE|FALSE]

핵심 옵션 설명 (--reset-configuration)

  • TRUE (권장): 패치 적용 시 변경되었던 설정 파일(standalone.xml 등)도 패치 이전 상태로 되돌립니다.
  • FALSE: 설정 파일은 현 상태를 유지하고 모듈(Jar)만 롤백합니다. 설정 충돌로 인해 서버 기동이 실패할 수 있으므로 주의해야 합니다.

실행 예시

# 설정까지 완벽하게 이전으로 복구
[standalone@localhost:9999 /] patch rollback --patch-id=CP19 --reset-configuration=true

4. 관리 콘솔(GUI)을 이용한 방법

CLI 사용이 어렵다면 웹 관리 콘솔에서도 동일한 작업을 수행할 수 있습니다.

  1. 접속: http://localhost:9990/console
  2. 메뉴: 상단 Patching 탭 선택
  3. 작업: 패치 마법사를 통해 파일 업로드 및 적용 (롤백 기능 포함)
JBoss Management Console Patching Screen

[그림] JBoss 관리 콘솔의 패치 관리 화면


Next Step:
패치 작업 전에는 만약을 대비해 standalone 또는 domain 디렉토리 전체를 압축하여 별도로 백업해두는 것을 강력히 권장합니다.

Open Stream →
#JBoss

[JBoss/Apache] mod_cluster 연동 완벽 가이드: 동적 클러스터링 및 멀티캐스트 설정

JBoss EAP 6와 Apache HTTP Server를 mod_cluster 모듈을 사용하여 연동하는 방법을 정리합니다. 정적인 설정 없이도 WAS의 추가/삭제를 자동으로 감지하는 동적 클러스터링을 구현하며, 멀티캐스트(Advertise) 설정을 중심으로 다룹니다.

0. 사전 준비 (Prerequisites)

  • OS: Windows 10 (테스트 환경)
  • Web Server: Apache 2.2.x (JBoss EWS 포함 버전 권장)
  • Middleware: JBoss EAP 6.4.x
버전 호환성 주의: Apache 버전에 맞는 mod_cluster 모듈(.so)을 사용해야 합니다. JBoss EWS(Enterprise Web Server) 패키지를 사용하면 이미 최적화된 모듈이 포함되어 있습니다.

1. Apache 설정 (Web Server)

Apache에 mod_cluster 관련 모듈을 로드하고, JBoss가 보낸 멀티캐스트 신호를 수신할 수 있도록 설정합니다.

1) 필수 모듈 복사

JBoss EAP 설치 경로에 포함된 mod_cluster 관련 모듈(.so)을 Apache의 modules 디렉토리로 복사합니다.

  • 원본 위치: [EAP_HOME]/modules/system/layers/base/native/lib64/httpd/modules
  • 복사할 파일:
    • mod_advertise.so
    • mod_manager.so
    • mod_proxy_cluster.so
    • mod_slotmem.so

2) mod_cluster.conf 작성

httpd.conf에서 include 할 설정 파일을 작성합니다. 핵심은 VirtualHost 내의 ServerAdvertise On 설정입니다.

# 필수 모듈 로드 (순서 중요)
LoadModule slotmem_module modules/mod_slotmem.so
LoadModule manager_module modules/mod_manager.so
LoadModule proxy_cluster_module modules/mod_proxy_cluster.so
LoadModule advertise_module modules/mod_advertise.so

# 공유 메모리 파일 위치 지정
MemManagerFile "C:/Apache/logs/mod_cluster"


  # JBoss 상태 관리 및 Advertise 수신 포트
  Listen 6666
  
    
      Order deny,allow
      Deny from all
      Allow from 127.0.0.1  # 보안상 로컬 접근만 허용 권장
    
    
    # 멀티캐스트 광고 활성화 (핵심)
    ServerAdvertise on
    EnableMCPMReceive

    # 관리 콘솔 URL
    
      SetHandler mod_cluster-manager
      Order deny,allow
      Allow from all
    
  

2. JBoss 설정 (Middleware)

JBoss가 기동될 때 자신의 정보를 멀티캐스트로 전파하거나, 프록시(Apache) 리스트를 받아오도록 설정합니다.

1) Instance ID 설정 (domain.xml)

Sticky Session을 위해 각 서버 인스턴스에 고유한 ID를 부여해야 합니다. ${jboss.server.name} 변수를 사용하면 편리합니다.

<subsystem xmlns="urn:jboss:domain:web:2.2" default-virtual-server="default-host" instance-id="${jboss.server.name}" native="false">
    <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/>
    <connector name="ajp" protocol="AJP/1.3" scheme="http" socket-binding="ajp"/>
    ...
</subsystem>

2) 소켓 바인딩 (Socket Binding) - 멀티캐스트 주소

동일 네트워크 내에 여러 JBoss 클러스터가 존재할 경우 혼선을 방지하기 위해 멀티캐스트 주소나 포트를 변경해야 합니다.

domain.xml 수정 (socket-binding-group):

<socket-binding-group name="full-ha-sockets" default-interface="public">
    
    ...
</socket-binding-group>
Tip: XML을 수정하지 않고 기동 시 파라미터(System Property)로 주소를 변경할 수 있습니다.
-Djboss.modcluster.multicast.address=224.10.1.1

3. 검증 및 테스트

설정 완료 후 Apache -> JBoss 순서로 기동합니다.

1) Apache 관리 콘솔 접속

브라우저에서 http://[Apache_IP]:6666/mod_cluster_manager 로 접속합니다.

  • 정상: 하단에 연결된 JBoss Node(Node Name, IP, Port) 리스트가 나타납니다.
  • 실패: 리스트가 비어있다면 멀티캐스트 통신이 방화벽에 막혀있거나, Advertise 설정이 잘못된 것입니다.

2) 클러스터링 동작 확인

애플리케이션 호출 시 세션이 유지되는지 확인하고, 한 쪽 노드를 셧다운 시켰을 때 Failover가 일어나는지 테스트합니다.

mod_cluster manager screen

[그림] mod_cluster 매니저 화면 (노드 인식 성공)


Next Step:
멀티캐스트 사용이 불가능한 클라우드 환경이라면, mod_cluster 설정을 TCP 유니캐스트(Proxy List 지정 방식)로 변경하여 구성하는 방법을 검토해 보십시오.

Open Stream →
#JBoss

[JBoss EAP 6] Windows Service 등록 가이드 (service.bat install)

Windows 환경에서 JBoss EAP 6를 백그라운드 서비스로 등록하여, 시스템 부팅 시 자동으로 시작되도록 설정하는 방법을 정리합니다. JBoss Native 패키지에 포함된 service.bat 스크립트를 사용합니다.

0. 사전 준비 (Prerequisites)

서비스 등록 작업을 수행하기 위해 관리자 권한(Run as Administrator)으로 실행된 명령 프롬프트(CMD)가 필요합니다.

시스템 환경 변수 설정

JBoss가 서비스로 구동될 때 참조할 필수 변수를 시스템 환경 변수에 등록해야 합니다.

  • JBOSS_HOME: JBoss EAP 6 설치 디렉토리 (예: C:\jboss-eap-6.4)
  • NOPAUSE: 값을 1로 설정.
    (※ 중요: 이 설정이 없으면 서비스 종료 시 배치 스크립트가 "Press any key..." 상태로 대기하여 서비스가 정상적으로 멈추지 않는 문제가 발생합니다.)

1. 서비스 설치 스크립트 위치

JBoss EAP 6는 Windows 서비스 등록을 위한 Native 유틸리티를 내장하고 있습니다. 해당 경로로 이동합니다.

:: 경로 이동 (설치 환경에 따라 경로가 다를 수 있음)
cd %JBOSS_HOME%\modules\system\layers\base\native\sbin

:: 파일 확인
dir service.bat

2. 서비스 등록 (Install Command)

service.bat install 명령어를 사용합니다. 운영 모드(Standalone / Domain)에 따라 옵션이 다릅니다.

Case A: Standalone Mode (단독 인스턴스)

가장 일반적인 구성입니다. 로그 레벨을 지정하여 설치합니다.

service.bat install /loglevel INFO

Case B: Domain Mode (도메인 구성)

도메인 컨트롤러(Domain Controller)와 연결해야 하므로 컨트롤러 정보가 필요합니다.

:: 기본 구문
service.bat install /controller [Host:Port] /host [HostName] /loglevel INFO

:: 사용 예시 (로컬이 마스터인 경우)
service.bat install /controller localhost:9990 /host master /loglevel INFO

주요 옵션 설명

옵션 설명
/name 서비스 이름 지정 (기본값: JBossEAP6)
/desc 서비스 설명 지정
/serviceuser 서비스를 실행할 Windows 계정 (DOMAIN\User)
/servicepass 실행 계정의 암호

3. 등록 확인 및 제어 (Verification)

설치가 완료되면 Windows 서비스 관리자에서 확인할 수 있습니다.

  1. 실행 창(Win+R) > services.msc 입력.
  2. "JBoss Enterprise Application Platform 6" 서비스를 찾습니다.
  3. 서비스를 시작(Start) 하고, 상태가 '실행 중'으로 바뀌는지 확인합니다.
  4. 브라우저로 JBoss 관리 콘솔이나 메인 페이지에 접속하여 실제 구동 여부를 체크합니다.

4. 서비스 삭제 (Uninstall)

설정을 변경하거나 경로를 바꿀 경우, 기존 서비스를 삭제하고 다시 등록해야 합니다.

:: 서비스 중지 (먼저 수행 필수)
service.bat stop

:: 서비스 삭제
service.bat uninstall
주의: 서비스 삭제 후 services.msc 목록에 잔상이 남아있다면, 윈도우를 재부팅하거나 관리자 권한 CMD에서 sc delete [서비스명]을 강제로 수행해야 할 수 있습니다.
Open Stream →
#JBoss

[JBoss EAP 6] Context Root를 루트(/)로 변경하기: Welcome Page 비활성화 설정

웹 애플리케이션을 배포할 때, URL 뒤에 붙는 프로젝트명(예: /MyApp) 없이 도메인 자체(예: http://localhost:8080/)로 접속하도록 설정하는 방법을 정리합니다. 애플리케이션 설정 변경과 JBoss 서버의 기본 Welcome Page 비활성화 작업이 필요합니다.

0. 배경 지식 (Context)

기본적으로 JBoss EAP는 루트 경로(/)에 "Welcome to JBoss"라는 기본 환영 페이지가 매핑되어 있습니다. 사용자의 애플리케이션을 루트 경로에 배포하려면, 이 기본 환영 페이지 기능을 끄고 애플리케이션이 그 자리를 차지하도록 설정해야 합니다.

Test Environment

  • OS: CentOS 7.2
  • WAS: JBoss EAP 6.4

1. 애플리케이션 설정 (jboss-web.xml)

애플리케이션(WAR) 내부의 설정 파일을 통해 "이 앱은 루트 컨텍스트(/)를 사용하겠다"고 선언합니다.

파일 생성 및 수정

  • 위치: [WAR_FILE]/WEB-INF/jboss-web.xml
  • 파일이 없다면 새로 생성하십시오.
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
    <!-- Context Root를 / 로 지정 -->
    <context-root>/</context-root>
</jboss-web>

2. 서버 설정 (domain.xml / standalone.xml)

애플리케이션 설정만으로는 부족합니다. JBoss 웹 서브시스템(Web Subsystem) 설정에서 enable-welcome-root 옵션을 false로 변경하여 기본 페이지를 비활성화해야 합니다.

설정 파일 선택

  • Domain Mode: [EAP_HOME]/domain/configuration/domain.xml
  • Standalone Mode: [EAP_HOME]/standalone/configuration/standalone.xml

수정 내용

도메인 모드의 경우, 현재 서버 그룹이 사용 중인 프로파일(Profile)(예: ha, full, full-ha)을 정확히 찾아 수정해야 합니다.

<!-- 해당 프로파일 내의 web 서브시스템 검색 -->
<subsystem xmlns="urn:jboss:domain:web:2.2" default-virtual-server="default-host" native="false">
    
    <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/>
    
    <!-- 핵심 수정 부분: enable-welcome-root를 false로 변경 -->
    <virtual-server name="default-host" enable-welcome-root="false">
        <alias name="localhost"/>
        <alias name="example.com"/>
    </virtual-server>

</subsystem>
주의 (Warning):
enable-welcome-root="true"인 상태에서 애플리케이션의 Context Root를 /로 설정하고 배포하면, JBoss 기동 시 "Context / is already in use" 에러가 발생하며 배포에 실패합니다.

3. 적용 및 검증 (Verification)

설정 변경 후에는 서버 재기동이 필요합니다.

재기동 및 접속 테스트

  1. JBoss 서버를 재기동합니다.
  2. 브라우저 주소창에 http://[서버IP]:8080/ 을 입력합니다.
  3. JBoss 기본 환영 페이지가 아닌, 내가 배포한 애플리케이션의 메인 페이지가 뜨는지 확인합니다.

Next Step:
루트 컨텍스트 설정이 완료되었다면, Apache 웹 서버와의 연동 시 mod_jkJkMount 설정도 /*로 변경하여 모든 요청을 WAS로 넘기도록 조정해야 합니다.

Open Stream →
#JBoss

[JBoss EAP 6] Session Clustering 완벽 가이드: 애플리케이션 설정부터 TCP 유니캐스트 전환까지

JBoss EAP 6의 HA(High Availability) 프로파일 환경에서 웹 애플리케이션의 세션 클러스터링을 구현하는 방법을 정리합니다. <distributable/> 선언부터 복제 트리거 설정, 그리고 웹 서버(Apache)와의 연동을 위한 jvmRoute 및 JGroups 네트워크 설정까지 다룹니다.

Test Environment

  • Middleware: JBoss EAP 6.4 (Domain Mode)
  • Profile: ha 또는 full-ha (클러스터링 모듈이 포함된 프로파일 필수)

1. 애플리케이션 설정 (Application Config)

세션 클러스터링이 작동하려면 먼저 애플리케이션이 "나는 분산 가능한 애플리케이션입니다"라고 선언해야 합니다.

1) web.xml 설정 (필수)

<distributable/> 태그가 없으면 JBoss는 해당 애플리케이션의 세션을 메모리에만 저장하고 복제하지 않습니다.

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" ...>
    
    <distributable/>

    <session-config>
        <session-timeout>30</session-timeout> </session-config>

</web-app>

2) jboss-web.xml 설정 (옵션/상세 튜닝)

세션 복제의 빈도와 범위를 세밀하게 제어하려면 WEB-INF/jboss-web.xml 파일을 설정합니다.

<jboss-web>
    <replication-config>
        <cache-name>web</cache-name>
        <!-- 복제 시점 결정 -->
        <replication-trigger>SET_AND_NON_PRIMITIVE_GET</replication-trigger>
        <!-- 복제 단위 결정 (SESSION: 전체 / ATTRIBUTE: 변경된 속성만) -->
        <replication-granularity>SESSION</replication-granularity>
    </replication-config>
</jboss-web>
Replication Trigger 설명:
  • SET: 세션 속성이 변경(setAttribute)될 때만 복제 (성능 우수).
  • SET_AND_GET: 세션을 읽기만 해도 복제 (데이터 일관성 최우선).
  • SET_AND_NON_PRIMITIVE_GET: (Default) 기본형이 아닌 객체를 읽거나 변경할 때 복제.

2. Sticky Session 설정 (jvmRoute)

웹 서버(Apache mod_jk/mod_cluster)가 로드밸런싱을 할 때, 사용자가 처음 접속한 JBoss 서버로 계속 요청을 보내게 하려면(Sticky Session), 세션 ID 뒤에 서버 식별자(jvmRoute)를 붙여야 합니다.

1) host.xml 설정 (서버별 식별자 부여)

각 서버 인스턴스에 고유한 jvmRoute 값을 시스템 프로퍼티로 정의합니다.

<servers>
    <server name="Server01" group="main-server-group" auto-start="true">
        <system-properties>
            <!-- 이 값은 workers.properties의 워커 이름과 일치해야 함 -->
            <property name="jvmRoute" value="Server01" boot-time="true"/>
        </system-properties>
    </server>
    
    <server name="Server02" ...>
        <system-properties>
            <property name="jvmRoute" value="Server02" boot-time="true"/>
        </system-properties>
    </server>
</servers>

2) domain.xml 설정 (Web Subsystem 적용)

정의한 시스템 프로퍼티(${jvmRoute})를 웹 서브시스템의 instance-id로 매핑합니다.

<subsystem xmlns="urn:jboss:domain:web:2.2" default-virtual-server="default-host" instance-id="${jvmRoute}" native="false">
    <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/>
    <!-- AJP 커넥터 필수 (mod_jk 연동 시) -->
    <connector name="ajp" protocol="AJP/1.3" scheme="http" socket-binding="ajp"/>
    ...
</subsystem>

3. JGroups 네트워크 설정 (UDP vs TCP)

JBoss 클러스터링 멤버 간의 통신은 기본적으로 UDP(Multicast)를 사용합니다. 하지만 클라우드 환경이나 네트워크 장비에서 멀티캐스트를 차단하는 경우 클러스터링이 되지 않습니다. 이럴 땐 TCP(Unicast)로 변경해야 합니다.

domain.xml 수정

jgroups 서브시스템의 default-stack 속성을 변경합니다.

<!-- 기존 UDP 설정 -->
<subsystem xmlns="urn:jboss:domain:jgroups:1.1" default-stack="udp">

<!-- TCP로 변경 -->
<subsystem xmlns="urn:jboss:domain:jgroups:1.1" default-stack="tcp">
    <stack name="tcp">
        <transport type="TCP" socket-binding="jgroups-tcp"/>
        ...
    </stack>
</subsystem>
주의: TCP로 변경 시, MPING(멀티캐스트 기반 멤버 검색) 대신 TCPPING을 사용하여 정적으로 IP 리스트를 지정해야 서로를 찾을 수 있는 환경이 많습니다. 네트워크 구성에 따라 추가 설정이 필요합니다.

4. 검증 (Verification)

  1. 서버 기동 확인: 서버 시작 로그에 Received new cluster view 메시지가 나타나며 멤버들이 서로를 인식하는지 확인합니다.
  2. 세션 ID 확인: 브라우저 개발자 도구(F12)에서 JSESSIONID 쿠키 값 뒤에 .Server01 처럼 jvmRoute 값이 붙는지 확인합니다.
  3. Failover 테스트: 한 쪽 서버를 강제로 내린 후(Shutdown), 다른 서버에서 로그인 풀림 없이 세션이 유지되는지 테스트합니다.
Open Stream →
#JBoss

[JBoss EAP 6] 도메인 모드(Domain Mode) 서버 로그 경로 변경 및 분리 설정

JBoss EAP 6를 도메인 모드(Domain Mode)로 운영할 때, 기본 로그 경로가 아닌 별도의 디스크 경로로 로그를 저장하는 방법을 정리합니다. domain.xmlpaths 설정과 logging 서브시스템을 수정하여 각 서버 인스턴스별로 로그 폴더를 동적으로 분리하는 구성을 다룹니다.

0. 배경 지식 (Context)

도메인 모드에서는 하나의 도메인 컨트롤러(Domain Controller)가 여러 서버 그룹과 인스턴스를 관리합니다. 로그 설정 시 가장 중요한 점은 "여러 서버가 동시에 실행될 때 로그 파일이 섞이지 않게 하는 것"입니다.

이를 위해 JBoss는 ${jboss.server.name}이라는 시스템 변수를 제공하여, 설정은 한 번만 하더라도 실제 로그는 각 서버의 이름으로 된 폴더에 쌓이도록 구성할 수 있습니다.


1. 사전 준비 및 백업

설정 변경 중 오타가 발생하면 JBoss 도메인 전체가 기동되지 않을 수 있습니다. 작업 전 반드시 설정 파일을 백업하십시오.

백업 대상

  • 파일 경로: [EAP_HOME]/domain/configuration/domain.xml
# 백업 예시
cp domain.xml domain.xml.bak_YYYYMMDD

2. 로그 경로(Path) 정의

먼저 로그를 저장할 물리적인 디렉토리 경로를 domain.xml 내에 논리적인 이름으로 정의해야 합니다. 이 설정은 파일의 상단 <paths> 섹션에 위치합니다.

domain.xml 수정

기존 <paths> 태그 내부에 새로운 경로를 추가합니다.

<paths>
    <!-- 기존 경로들 ... -->
    
    <!-- 신규 로그 경로 정의 -->
    <!-- name: 설정에서 사용할 논리적 이름 / path: 실제 파일 시스템 경로 -->
    <path name="server.log.dir" path="D:\app\log"/>
</paths>
주의: Windows 환경에서는 백슬래시(\)를 사용하고, Linux 환경에서는 슬래시(/)를 사용하여 경로를 지정하십시오. 또한 해당 경로에 JBoss 실행 계정이 쓰기 권한을 가지고 있어야 합니다.

3. 프로파일(Profile) 로깅 설정 적용

위에서 정의한 경로를 실제로 사용하도록 로깅 서브시스템(Subsystem)을 수정합니다. 도메인 모드에는 여러 프로파일(default, ha, full, full-ha 등)이 존재하므로, 현재 운영 중인 서버 그룹이 사용하는 프로파일을 정확히 찾아 수정해야 합니다.

domain.xml 수정 (logging subsystem)

<profile name="ha"> (예시) 내부의 로깅 설정을 찾아 file-handler 부분을 수정합니다.

<profile name="ha">
    <subsystem xmlns="urn:jboss:domain:logging:1.2">
        <!-- Console Handler 생략 -->

        <!-- File Handler 수정 -->
        <periodic-rotating-file-handler name="FILE" autoflush="true">
            <formatter>
                <named-formatter name="PATTERN"/>
            <formatter>
            
            <!-- 핵심 설정 부분 -->
            <!-- relative-to: 위에서 정의한 경로 변수 참조 -->
            <!-- path: 서버 이름별로 폴더 자동 생성 -->
            <file relative-to="server.log.dir" path="${jboss.server.name}/server.log"/>
            
            <suffix value=".yyyy-MM-dd"/>
            <append value="true"/>
        </periodic-rotating-file-handler>
        
        <!-- 이하 생략 -->
    </subsystem>
</profile>

설정 설명

  • relative-to="server.log.dir": 2번 단계에서 정의한 D:\app\log를 기준 경로로 잡습니다.
  • path="${jboss.server.name}/server.log": 기준 경로 하위에 서버 인스턴스 이름(예: Server1, Server2)으로 폴더를 만들고 그 안에 server.log를 생성합니다.

4. 적용 및 검증 (Verification)

domain.xml은 정적 설정 파일이므로 변경 사항을 적용하려면 도메인 전체 재기동이 필요합니다.

재기동

# Linux
[EAP_HOME]/bin/domain.sh

# Windows
[EAP_HOME]\bin\domain.bat

결과 확인

서버가 기동된 후, 탐색기나 쉘을 통해 지정한 경로(D:\app\log)에 서버별 폴더가 생성되었는지 확인합니다.

D:\app\log\
    ├── Server1\
    │     └── server.log
    └── Server2\
          └── server.log

Next Step:
로그 경로 변경에 성공했다면, 운영 편의를 위해 로그 파일의 보관 주기(Retention Policy)를 설정하거나, 로그 포맷(Formatter)을 변경하여 가독성을 높이는 작업을 고려해 보십시오.

Open Stream →