Oracle Internet Directory(OID) 확장 Part 3: 웹로직/JVM 최적화 완벽 가이드

Oracle Internet Directory Enterprise Scaling - Part 3

이 글은 “Oracle Internet Directory 확장 가이드” 시리즈의 세 번째 이야기입니다. 지난 시리즈에서는 기업 환경에서 OID를 효과적으로 확장하는 방법을 다뤘습니다. 앞선 구성이 낯설다면 이전 편을 먼저 읽어보세요.

OID 성능의 핵심 이해하기

OID 관련 성능 문제에서는 LDAP 서버·데이터베이스와 WebLogic 애플리케이션의 처리 경로를 먼저 구분합니다. WebLogic 스레드와 JVM 설정은 해당 JVM에서 실행되는 작업에 적용되며, OID LDAP 처리 전체를 직접 제어하는 설정으로 해석하면 안 됩니다. 이 글은 WebLogic의 작업 처리 제약과 JVM 메모리·GC 설정을 나누어 설명합니다.

웹로직(WebLogic) 설정

WebLogic Server의 스레드와 작업 우선순위 설정은 동시에 처리할 작업량과 대기 방식에 영향을 줍니다.

스레드 풀(Thread Pool) 관리

사용자 수·대기 요청 수·실행 스레드 수는 서로 다른 지표입니다. 아래 XML은 설정 형식을 보여 주는 예시이며, 값은 대상 환경에서 측정해 정해야 합니다.

<!-- config.xml 서버 수준: self-tuning 스레드 풀 범위(ServerMBean) -->
<server>
<name>wls_ods1</name>
<self-tuning-thread-pool-size-min>20</self-tuning-thread-pool-size-min>
<self-tuning-thread-pool-size-max>200</self-tuning-thread-pool-size-max>
</server>

기존 글은 평균 2.3초의 응답 지연과 특정 거래 시간대의 타임아웃을 설명합니다. 원인을 판단하려면 같은 시간대의 큐 대기, 스레드 상태와 하위 시스템 지연을 대조해야 합니다.

아래 변경 예시도 검증된 권장 설정이 아닙니다. 먼저 설정 위치와 스키마를 해당 버전 문서에서 확인하세요.

<!-- config.xml 서버 수준(예시 값) -->
<server>
<name>wls_ods1</name>
<self-tuning-thread-pool-size-min>50</self-tuning-thread-pool-size-min>
<self-tuning-thread-pool-size-max>400</self-tuning-thread-pool-size-max> <!-- 400은 기본값 -->
</server>

설정 이름이 비슷해도 서버 스레드 풀과 Work Manager 제약의 의미는 다릅니다. 다음 설명에서는 그 차이를 구분합니다.

최소 스레드 수(50개) 설정의 의미

<min-threads-constraint>50</min-threads-constraint>

min-threads-constraint는 영향을 받는 작업의 최소 스레드 할당 제약입니다. 시작할 때 전용 스레드 50개를 미리 만드는 설정이나 지연 없는 처리를 보장하는 설정이 아닙니다. 서버 풀의 최소 크기와도 구분해야 합니다.

최대 스레드 수(400개)

max-threads-constraint는 해당 제약을 공유하는 작업의 동시 실행 스레드 수를 제한합니다. 값 400은 이 글의 예시이며 서버 전체 풀의 최대 크기나 동시 인증 처리 용량을 입증하지 않습니다.

<max-threads-constraint>400</max-threads-constraint>

스레드 수 검토에서는 다음 관측값을 함께 비교합니다.

  • CPU 사용량과 실행·대기 작업의 비율
  • 실제 스택 설정과 힙 외 메모리를 포함한 프로세스 사용량
  • DB·LDAP 등 하위 연결 풀의 한도와 응답 지연

코어당 25~50개나 스레드당 512KB~1MB를 보편적인 최적 범위로 사용하지 않습니다. 기존 사례가 400을 선택한 근거는 원본 측정 자료가 필요합니다.

대기열 크기(Queue Size)와 작업 중단 감지(Stuck Thread Detection)

<!-- 대기 요청 한도는 Work Manager의 capacity 제약으로 지정 -->
<work-manager>
<name>OIDWorkManager</name>
<capacity>
<name>OID-Capacity</name>
<count>500</count>
</capacity>
</work-manager>

WebLogic에는 thread-pool이나 queue-size라는 요소가 없습니다. 서버 전체 self-tuning 스레드 풀은 SelfTuningThreadPoolSizeMin/Max(Max 기본값 400)로 범위를 정하고, 대기 요청 한도는 Work Manager의 capacity 제약(기본 -1, 제한 없음)으로 지정합니다. StuckThreadMaxTime은 서버 설정이며 기본값이 이미 600초이고, 12.2.1.4에서는 서버 실패 트리거의 MaxStuckThreadTime으로 대체되는 deprecated 속성입니다. 장시간 실행 진단용 값이며 요청 완료나 자동 복구를 보장하지 않습니다. 큐가 길어지면 메모리와 대기 시간이 늘 수 있습니다.

스레드 풀 최적화의 효과

스레드 수 증가와 무제한 대기를 개선의 증거로 삼지 않습니다. 같은 부하에서 완료율·지연 분포·오류·자원 사용량을 비교하세요.

Work Manager(워크 매니저) 설정

Work Manager는 실제 WebLogic 애플리케이션 작업에 스케줄링 지침과 제약을 적용합니다. 지연에 민감한 인증 작업을 구분할 수 있지만 적용 대상·dispatch policy·하위 시스템 한도를 먼저 확인해야 합니다. 아래 기존 XML은 설치 가능한 설정으로 검증되지 않았습니다.

<!-- Work Manager 하나에 request class는 하나: 우선순위가 둘이면 Work Manager도 둘 -->
<work-manager>
<name>OID-Critical-WM</name>
<fair-share-request-class>
<name>Critical-Ops</name>
<fair-share>80</fair-share>
</fair-share-request-class>
<min-threads-constraint>
<name>Critical-Min</name>
<count>25</count>
</min-threads-constraint>
</work-manager>

<work-manager>
<name>OID-Routine-WM</name>
<fair-share-request-class>
<name>Routine-Ops</name>
<fair-share>20</fair-share>
</fair-share-request-class>
<max-threads-constraint>
<name>OID-Max</name>
<count>400</count>
</max-threads-constraint>
</work-manager>

최소·최대 스레드 제약과 fair share는 각각 다른 역할을 합니다. 이 예시의 이름이나 숫자만으로 전용 풀과 SLA가 구성됐다고 판단하지 않습니다.

<min-threads-constraint>
<name>Critical-Min</name>
<count>25</count>
</min-threads-constraint>

최소 스레드 제약 25는 시작 시 전용 스레드 25개를 예약한다는 뜻이 아닙니다. 관련 대기 작업의 스케줄링에 영향을 주지만, DB·LDAP 지연이나 전체 자원 부족까지 제거하지는 않습니다. min-threads-constraint에는 이름과 개수만 들어가며, pool-name은 연결 풀 크기에 맞추는 max-threads-constraint에 쓰는 요소입니다. 다음 fair-share 값은 상대적 가중치(기본 50)이며, request class는 Work Manager마다 하나씩 둡니다.

<fair-share-request-class>
    <name>Critical-Ops</name>
    <fair-share>80</fair-share>
</fair-share-request-class>
<fair-share-request-class>
    <name>Routine-Ops</name>
    <fair-share>20</fair-share>
</fair-share-request-class>

80과 20은 고정 CPU·메모리 배분율이 아닙니다. 충분한 경쟁 부하에서 스레드 사용 시간의 상대적 배분을 유도하는 값이며, 모든 요청의 지연이나 비율을 보장하지 않습니다.

JVM 최적화: 메모리 관리의 기술

JVM 분석에서는 힙·클래스 메타데이터·스택 등 힙 외 사용량을 구분하고, 평가하는 변경마다 GC 로그·버전·부하 기록을 남깁니다.

JVM 메모리 구조의 이해

JVM의 주요 메모리 영역은 저장하는 데이터에 따라 구분합니다.

JVM Memory Structure
웹로직 JVM 메모리 구조

세대별 메모리의 기본 역할

  • Eden은 새 객체가 주로 할당되는 영역입니다. 큰 객체 등은 GC 방식에 따라 다른 경로를 사용할 수 있습니다.
  • Survivor 영역은 수집 후 살아남은 객체를 다루며, 이후 이동·승격은 GC 정책과 객체 나이에 따라 달라집니다.
  • Old 영역에는 오래 살아남거나 승격된 객체 등이 저장됩니다. 오래 남았다는 사실이 업무상 가치나 누수 없는 상태를 뜻하지는 않습니다.

G1에서는 세대를 고정된 연속 구획으로만 이해하지 말고 역할이 부여된 region들의 집합으로 봅니다. 도표는 개념도이며 설치 JVM의 실제 배치 확인 결과가 아닙니다.

초기 상황 평가

기존 글의 초기 JVM 예시입니다. 옵션 지원 여부와 실제 실행 JVM을 확인하기 전에는 적용하지 마세요.

# 초기 메모리 설정
JAVA_OPTIONS="-Xms2048m -Xmx4096m"
JAVA_OPTIONS="${JAVA_OPTIONS} -XX:+UseParallelGC"

초기·최대 힙 크기만으로 GC 지연의 원인을 확정할 수 없습니다. 중단 시간과 그 원인(단편화, 힙 리사이징 등)은 GC 로그로 확인합니다.

메모리 설정: 최적의 공간 구성하기

아래는 기존 글의 변경 후 옵션 예시입니다. 검증된 권장 세트가 아니며, WebLogic과 JDK의 지원 조합·메모리 예산·부하 시험을 먼저 확인해야 합니다.


# Optimized memory settings JAVA_OPTIONS="${JAVA_OPTIONS} -Xms6144m -Xmx6144m" # G1GC configuration JAVA_OPTIONS="${JAVA_OPTIONS} -XX:+UseG1GC" JAVA_OPTIONS="${JAVA_OPTIONS} -XX:MaxGCPauseMillis=200" JAVA_OPTIONS="${JAVA_OPTIONS} -XX:ParallelGCThreads=8" JAVA_OPTIONS="${JAVA_OPTIONS} -XX:ConcGCThreads=2" JAVA_OPTIONS="${JAVA_OPTIONS} -XX:InitiatingHeapOccupancyPercent=45" # Metaspace configuration JAVA_OPTIONS="${JAVA_OPTIONS} -XX:MetaspaceSize=256m" JAVA_OPTIONS="${JAVA_OPTIONS} -XX:MaxMetaspaceSize=512m"

옵션의 역할과 예시 값의 적용 조건을 나누어 살펴봅니다.

힙 크기 (Heap Size) 설정

JAVA_OPTIONS="${JAVA_OPTIONS} -Xms6144m -Xmx6144m"

-Xms와 -Xmx를 모두 6GB로 두면 힙 크기 변동을 제한할 수 있습니다. 6GB가 보편적인 권장값이거나 지연 원인이 해결됐다는 뜻은 아닙니다. OS·스택·Metaspace 등 힙 외 사용량을 포함해 전체 메모리 여유를 검토하세요.

가비지 컬렉션(Garbage Collection) 전략

JAVA_OPTIONS="${JAVA_OPTIONS} -XX:+UseG1GC"
JAVA_OPTIONS="${JAVA_OPTIONS} -XX:MaxGCPauseMillis=200"
JAVA_OPTIONS="${JAVA_OPTIONS} -XX:ParallelGCThreads=8"

G1은 힙을 region 단위로 관리합니다. MaxGCPauseMillis=200은 중단 시간 목표이며 보장된 상한이 아닙니다. ParallelGCThreads=8은 병렬 GC 작업의 스레드 설정입니다. 두 값을 적용하기 전 지원 JDK와 실제 CPU·GC 로그를 확인하세요.

메모리 관리 트리거 설정

JAVA_OPTIONS="${JAVA_OPTIONS} -XX:InitiatingHeapOccupancyPercent=45"
JAVA_OPTIONS="${JAVA_OPTIONS} -XX:ConcGCThreads=2"

Fusion Middleware 12.2.1.4는 JDK 8에서 동작합니다. JDK 8의 G1에서 InitiatingHeapOccupancyPercent는 동시 마킹을 시작하는 전체 Java 힙 점유율 기준입니다(기본 45). 관측값으로 기준을 조정하는 적응형 IHOP는 JDK 9부터 도입됐습니다. ConcGCThreads는 동시 GC 작업 스레드 수와 관련되며 stop-the-world 단계는 여전히 존재합니다.

메타스페이스 설정(Metaspace Configuration)

JAVA_OPTIONS="${JAVA_OPTIONS} -XX:MetaspaceSize=256m"
JAVA_OPTIONS="${JAVA_OPTIONS} -XX:MaxMetaspaceSize=512m"

Metaspace는 클래스 메타데이터용 native 메모리입니다. MetaspaceSize=256m는 처음 GC를 유발하는 메타데이터 임계값과 관련되며, 256MB의 초기 영역을 예약하는 옵션으로 설명하면 안 됩니다. MaxMetaspaceSize=512m는 최대 크기 제한입니다. 실제 옵션 의미·기본값과 한도 도달 위험은 지원 JDK 문서와 사용량을 함께 확인하세요.

메모리 관리 트리거 상세

마킹 시작 조건과 동시 GC 스레드 수를 각각 조정한 뒤 로그에서 실제 영향을 확인합니다.

InitiatingHeapOccupancyPercent=45를 적용하기 전에 사용 중인 Fusion Middleware가 인증된 JDK 버전을 확인합니다.

JAVA_OPTIONS="${JAVA_OPTIONS} -XX:InitiatingHeapOccupancyPercent=45"

JDK 8에서는 전체 힙 기준의 고정 임계값이고, JDK 9 이후에는 적응형 IHOP가 마킹 시간과 할당 속도를 관측해 기준을 조정합니다. 어느 경우든 실제 마킹 시작 시점은 GC 로그로 확인하세요. 다음은 동시 GC 스레드 수 예시입니다.

JAVA_OPTIONS="${JAVA_OPTIONS} -XX:ConcGCThreads=2"

ConcGCThreads=2는 예시 값입니다. 동시 작업이 애플리케이션 CPU와 경쟁할 수 있으며, 일부 GC 단계의 중단은 남습니다. 변경 후 중단 시간·마킹 진행·회수 여유를 함께 확인하세요.

효과 판정 방법

변경 효과를 인정하려면 동일 조건의 지연·완료율·오류와 자원 압박이 함께 개선되는지 확인해야 합니다. 설정 숫자와 사용자 수만으로 안정성을 결론내리지 않습니다.

Oracle Internet Directory 확장 시리즈 Part 3: 결론과 핵심 요약

WebLogic 작업 제약과 JVM 메모리·GC 설정은 적용 계층과 버전을 구분해서 검토합니다. 기존 예시는 설치 가능한 설정이나 성능 보증으로 사용하지 않습니다.

우선 확인할 것은 WebLogic 요청의 큐 대기·동시 실행·하위 시스템 지연, 그리고 JVM의 힙 외 메모리와 GC 중단 분포입니다. 각 설정은 같은 부하에서 측정한 결과로 판단합니다.

성능 설정은 한 번 바꾸고 끝낼 수 있는 작업이 아닙니다. 부하가 달라지면 측정 결과도 달라질 수 있습니다. 이 시리즈의 점검 항목을 참고해 변경 전후를 비교하고, 해당 환경에 맞는 설정을 선택하세요.

위로 스크롤