Java 애플리케이션 컨테이너화

이 문서에서는 Java 애플리케이션을 컨테이너화하기 위한 권장 전략 및 설정에 대한 개요를 제공합니다.

Java 애플리케이션을 컨테이너화할 때 컨테이너를 사용할 수 있는 CPU 시간을 신중하게 고려합니다. 그런 다음 총 메모리 양과 JVM(Java Virtual Machine)의 힙 크기 모두에서 사용할 수 있는 메모리 양을 고려합니다. 컨테이너화된 환경에서 애플리케이션은 모든 프로세서에 액세스할 수 있으므로 여러 스레드를 병렬로 실행할 수 있습니다. 그러나 일반적으로 컨테이너에는 CPU에 대한 액세스를 제한할 수 있는 CPU 할당량이 적용됩니다.

JVM에는 JAVA 애플리케이션의 성능에 크게 영향을 줄 수 있는 CPU 할당량에 따라 "사용 가능한 프로세서" 수를 결정하는 추론이 있습니다. 컨테이너 자체에 할당된 메모리와 JVM에 대한 힙 영역의 크기는 프로세서만큼 중요합니다. 이러한 요인은 GC(가비지 수집기)의 동작과 시스템의 전반적인 성능을 결정합니다.

새 애플리케이션 컨테이너화

새 애플리케이션에 대한 Java 워크로드를 컨테이너화하는 경우 메모리를 고려할 때 다음 두 가지를 고려해야 합니다.

  • 컨테이너 자체에 할당된 메모리입니다.
  • Java 프로세스에 사용할 수 있는 메모리 양입니다.

JVM 기본 인체 공학 이해

애플리케이션에는 시작점 및 설정이 필요합니다. JVM에는 시스템의 사용 가능한 프로세서 수와 메모리 양을 기반으로 하는 미리 정의된 값이 있는 기본 인체 공학이 있습니다. 다음 표에 표시된 기본값은 특정 시작 플래그 또는 매개 변수 없이 JVM을 시작할 때 사용됩니다.

다음 표에서는 사용 가능한 리소스에 사용되는 기본 GC를 보여 줍니다.

사용 가능한 리소스 기본 GC
모든 수의 프로세서
최대 1791MB의 메모리
SerialGC
2개 이상의 프로세서
1792MB 이상의 메모리
G1GC

다음 표에서는 JVM이 실행되는 환경에서 사용할 수 있는 메모리 양에 따라 기본 최대 힙 크기를 보여 줍니다.

사용 가능한 메모리 기본 최대 힙 크기
최대 256MB 사용 가능한 메모리의 50%
256MB ~512MB ~127MB
512MB 이상 사용 가능한 메모리의 25%

기본 초기 힙 크기 는 사용 가능한 메모리의 1/64입니다.

이러한 값은 OpenJDK 11 이상 및 Microsoft Build of OpenJDK, Azul Zulu, Eclipse Temurin, Oracle OpenJDK 등을 비롯한 대부분의 배포에 유효합니다.

컨테이너 메모리 확인

애플리케이션의 요구 사항 및 고유한 사용 패턴에 따라 작업 부하에 가장 적합한 컨테이너 메모리 양을 선택합니다. 예를 들어 애플리케이션이 큰 개체 그래프를 만드는 경우 작은 개체 그래프가 많은 애플리케이션에 필요한 것보다 많은 메모리가 필요할 수 있습니다.

할당할 메모리의 양을 모르는 경우 좋은 시작점은 4GB입니다.

JVM 힙 메모리 확인

JVM 힙 메모리를 할당하는 경우 JVM에는 JVM 힙에 사용되는 메모리보다 더 많은 메모리가 필요합니다. 최대 JVM 힙 메모리를 설정하면 컨테이너 OOM(메모리 부족) 오류 및 컨테이너 크래시가 발생하므로 컨테이너 메모리 양과 같아서는 안 됩니다.

JVM 힙에 컨테이너 메모리의 75%를 할당합니다.

OpenJDK 11 이상에서는 다음과 같은 방법으로 JVM 힙 크기를 설정할 수 있습니다.

설명 Flag 예제
고정 값 -Xmx -Xmx4g
동적 값 -XX:MaxRAMPercentage -XX:MaxRAMPercentage=75

최소/초기 힙 크기

환경이 컨테이너와 같이 JVM 인스턴스에 예약된 특정 양의 메모리가 보장되는 경우 최소 힙 크기 또는 초기 힙 크기를 최대 힙 크기와 동일한 크기로 설정해야 합니다. 이 설정은 메모리를 OS로 해제하는 작업을 수행해서는 안 되었음을 JVM에 나타냅니다.

최소 힙 크기를 설정하려면 절대 크기 또는 -XX:InitialRAMPercentage 백분율 양에 사용합니다-Xms.

Important

이름에 따라 플래그 -XX:MinRAMPercentage는 시스템에서 최대 256MB의 RAM을 사용할 수 있는 시스템의 기본 최대 RAM 비율을 설정하는 데 사용됩니다.

Chart showing the default heap size on OpenJDK 17.

사용할 GC 결정

이전에는 시작할 JVM 힙 메모리의 양을 결정했습니다. 다음 단계는 GC를 선택하는 것입니다. 최대 JVM 힙 메모리의 양은 GC를 선택하는 요인인 경우가 많습니다. 다음 표에서는 각 GC의 특징을 설명합니다.

요소 SerialGC ParallelGC G1GC ZGC ShenandoahGC
코어 수 1 2 2 2 2
다중 스레드
Java 힙 크기 <4GB <4GB >4GB >4GB >4GB
일시 중지 예(<1ms) 예(<10ms)
간접비 최솟값 최솟값 일반형 일반형 일반형
비상 대기 시간 효과 높음 높음 높음 낮음 일반형
JDK 버전 모두 모두 JDK 8 이상 JDK 17 이상 JDK 11 이상
적합한 대상 단일 코어 작은 힙 모든 힙 크기의 다중 코어 작은 힙 또는 일괄 처리 워크로드 중대형 힙에서 응답(요청-응답/DB 상호 작용) 중대형 힙에서 응답(요청-응답/DB 상호 작용) 중대형 힙에서 응답(요청-응답/DB 상호 작용)

대부분의 범용 마이크로 서비스 애플리케이션의 경우 병렬 GC로 시작합니다.

필요한 CPU 코어 수 확인

SerialGC 이외의 GC의 경우 두 개 이상의 vCPU 코어 또는 Kubernetes에서 2000mcpu_limit 이상을 사용하는 것이 좋습니다. 컨테이너화된 환경에서 1개 미만의 vCPU 코어를 선택하지 않는 것이 좋습니다.

시작할 코어 수를 모르는 경우 2개의 vCPU 코어를 선택하는 것이 좋습니다.

시작점 선택

Kubernetes, OpenShift, Azure Spring Apps, Azure Container Apps 및 Azure 앱 Service와 같은 컨테이너 오케스트레이션 환경에서 두 개의 복제본(replica) 또는 인스턴스로 시작하는 것이 좋습니다. 다음 표에서는 새 Java 애플리케이션의 컨테이너화에 권장되는 시작점을 요약합니다.

vCPU cores 컨테이너 메모리 JVM 힙 크기 GC 복제본
2 4GB 75% ParallelGC 2

사용할 JVM 매개 변수는 다음과 같습니다. -XX:+UseParallelGC -XX:MaxRAMPercentage=75

기존(온-프레미스) 애플리케이션 컨테이너화

애플리케이션이 온-프레미스 또는 클라우드의 VM에서 이미 실행 중인 경우 다음으로 시작하는 것이 좋습니다.

  • 애플리케이션이 현재 액세스할 수 있는 메모리 양과 동일합니다.
  • 애플리케이션에서 현재 사용할 수 있는 CPU(vCPU 코어)의 수와 동일합니다.
  • 현재 사용하는 것과 동일한 JVM 매개 변수입니다.

vCPU 코어 및/또는 컨테이너 메모리 조합을 사용할 수 없는 경우 가장 가까운 메모리를 선택하여 vCPU 코어와 컨테이너 메모리를 반올림합니다.

다음 단계

이제 Java 애플리케이션 컨테이너화에 대한 일반적인 권장 사항을 이해했으므로 다음 문서를 계속 진행하여 컨테이너화 기준을 설정합니다.