jvm

2 개의 포스트

수천 개의 API/BATCH 서버를 하나의 설정 체계로 관리하기 (새 탭에서 열림)

토스페이먼츠는 수천 개의 API 서버와 배치 설정을 관리하기 위해 설정을 단순한 텍스트가 아닌 '진화하는 코드'로 정의하여 운영합니다. 복사-붙여넣기식의 중복 설정을 제거하기 위해 오버레이 아키텍처와 템플릿 패턴을 도입했으며, 이를 통해 오타나 설정 오류로 인한 대규모 정산 장애 리스크를 원천 차단합니다. 결과적으로 인프라 설정을 테스트 가능한 영역으로 끌어올려 대규모 하이브리드 클라우드 환경에서도 높은 안정성과 유연성을 확보했습니다. ### 실시간 API 서버: 오버레이와 템플릿의 결합 * **오버레이 아키텍처:** 설정을 `global`, `cluster`, `phase`, `application` 순서의 계층형 구조로 설계하여 하위 계층이 상위 계층의 기본값을 덮어쓰도록 구성했습니다. 이를 통해 공통 설정은 한 번만 정의하고 각 환경에 필요한 차이점만 관리할 수 있습니다. * **템플릿 패턴 도입:** YAML의 단순 오버레이만으로는 해결하기 어려운 긴 문자열(예: JVM 옵션) 내의 특정 값만 수정하기 위해 `{{MAX_HEAP}}`과 같은 변수 치환 방식을 사용합니다. * **동적 설정 주입:** 설정 파일 내부에 파이썬 스크립트를 삽입하여 랜덤 포트 생성이나 외부 API 호출을 통한 동적 값 할당이 가능하며, 클러스터 이름에 따른 조건부 로직을 적용해 복잡한 환경 변수 요구사항을 해결합니다. ### 배치 서버: DSL과 GitOps를 통한 단순화 * **Jenkins 기반의 단순화:** 대규모 정산 데이터를 다루는 배치 환경일수록 단순함이 강력하다는 원칙 아래, Jenkins를 활용하면서도 수동 조작의 단점을 보완하는 방향을 택했습니다. * **Groovy DSL 활용:** Jenkins의 웹 UI를 통한 수동 설정을 배제하고, Groovy 기반의 자체 DSL(Domain Specific Language)을 구축하여 수천 개의 배치 Job을 코드 형태로 관리합니다. * **GitOps 체계:** 모든 배치 설정을 코드 저장소에서 관리하고 CI/CD 파이프라인과 통합함으로써, 개발자가 직접 Jenkins에 접속하지 않고도 표준화된 환경에서 배치 작업을 배포할 수 있도록 개선했습니다. ### 인프라의 코드화와 검증 자동화 * **테스트 가능한 설정:** 설정값에 대한 오타나 논리적 오류를 방지하기 위해 설정 코드에 대한 유닛 테스트를 수행합니다. 이를 통해 수천 개의 설정 중 단 하나의 오타가 치명적인 금융 장애로 이어지는 것을 사전에 방지합니다. * **유연한 확장성:** 고정된 설정 체계에 안주하지 않고, 인프라의 변화와 개발자의 요구사항에 맞춰 설정 인프라 자체가 계속해서 진화할 수 있는 구조를 지향합니다. 단순히 설정 파일을 잘 작성하는 것에 그치지 않고, 인프라 설정을 애플리케이션 코드와 동일한 수준의 설계와 테스트를 거쳐 관리하는 것이 대규모 시스템의 안정성을 보장하는 핵심입니다. 초기에 다소 복잡해 보일 수 있는 오버레이나 DSL 도입은 장기적으로 중복을 제거하고 휴먼 에러를 막는 가장 확실한 투자입니다.

API 호출식 웜업의 부작용을 넘어서 : 라이브러리만 데우는 JVM 웜업 (새 탭에서 열림)

JVM 기반 웹 애플리케이션은 실행 초기 JIT(Just-In-Time) 컴파일러의 최적화 과정에서 발생하는 응답 지연 문제를 해결하기 위해 '웜업' 과정이 필수적입니다. 기존의 API 호출식 웜업은 데이터 오염이나 외부 시스템 부하와 같은 부작용을 초래할 수 있으나, 본 발표에서는 이를 극복하기 위해 핵심 라이브러리만을 직접 예열하는 '라이브러리 웜업' 방식을 제안합니다. 이 기술을 통해 부작용 없이 애플리케이션 배포 직후의 성능을 안정적으로 확보할 수 있습니다. **JVM 웜업의 필요성과 기존 방식의 한계** * JVM은 실행 초기에 인터프리터 방식으로 동작하다가, 반복되는 코드를 JIT 컴파일러가 네이티브 코드로 최적화하는 과정을 거치며 성능이 올라갑니다. * 이 최적화가 완료되기 전까지는 응답 시간이 길어지거나 CPU 사용량이 급증하는 현상이 발생하므로, 실제 트래픽이 들어오기 전 코드를 미리 실행하는 웜업이 필요합니다. * 기존의 API 호출 방식은 가짜 요청을 보내는 과정에서 DB 데이터 정합성을 해칠 수 있고, 외부 API 호출에 따른 불필요한 연동 부하를 발생시키는 단점이 있습니다. **라이브러리 웜업의 핵심 아이디어와 구현** * 비즈니스 로직 전체를 수행하는 대신, 애플리케이션에서 성능 비중이 크고 공통적으로 사용되는 '라이브러리 코드'만을 타겟팅하여 예열합니다. * 예를 들어 JSON 파싱, 암호화, 복잡한 수치 계산 모듈 등 JIT 컴파일 임계치(Threshold)를 넘겨야 하는 핵심 메서드들을 반복 호출하도록 설계합니다. * 애플리케이션 시작 단계(Post-Construct 등)에서 비즈니스 로직과는 독립된 웜업 코드를 실행함으로써 데이터 오염의 위험을 원천적으로 차단합니다. **성능 검증 및 실무적 이점** * 라이브러리 웜업 적용 후, 배포 초기에 발생하는 응답 속도의 '튀는 현상(Spike)'이 현저히 감소하고 전체적인 레이턴시가 안정화됨을 확인했습니다. * API 호출 방식보다 구현이 단순하고 외부 의존성이 적어 관리가 용이하며, 배포 파이프라인의 안정성을 높이는 데 기여합니다. * 다만, 모든 비즈니스 경로를 커버하지는 못하므로 성능 영향도가 높은 핵심 모듈을 선별하여 집중적으로 웜업하는 전략이 유효합니다. 빠른 스케일 아웃이 필요한 마이크로서비스 환경이나 지연 시간에 민감한 실시간 서비스라면, API 기반 웜업의 대안으로 이와 같은 라이브러리 단위의 정밀한 웜업 도입을 적극 권장합니다.