
핵심요약
토스페이먼츠는 수천 개의 API 및 배치 서버 설정을 관리하기 위해 '설정의 코드화'와 '추상화'를 핵심으로 하는 접근 방식을 도입했습니다. 오버레이 아키텍처, 템플릿 패턴, Job-DSL 플러그인 어댑터, Dynamic Provisioning 등을 통해 설정 중복과 관리 복잡성을 해결하고 개발자 경험과 인프라 안정성을 향상시켰습니다.
수천 개의 API/BATCH 서버 설정을 단일 체계로 관리하기: 토스페이먼츠의 여정
문제점: 설정 중복과 관리의 복잡성
- 오타 및 실수 위험: 수천 개의 API 및 배치 서버 설정을 수동으로 관리할 때 오타로 인한 심각한 장애 발생 가능성 (예: 50억 규모 정산 배치 오류).
- 코드 중복과 유사성: API 서버 설정의 복잡성 증대 및 실수 발생 빈도 증가.
- 개발자 반복 작업: Jenkins Web UI를 통한 수동 설정, 장비별 다른 Java 버전 및 실행 스크립트.
- 메모리 부족: Jenkins 워커 장비의 메모리 부족으로 인한 프로세스 비정상 종료.
해결책: 설정의 코드화 및 추상화
Part 1: 실시간 API 서버 설정
- 오버레이 아키텍처: 설정을
global,cluster,phase,app등 계층으로 구성하고 우선순위에 따라 조합하여 최종 설정 생성. 각 계층은 특정 요구사항(예: K8S cluster, app-group, phase)을 반영. - 템플릿 패턴: YAML 값 내부에서 중괄호
{}를 사용하여 동적으로 값을 채우는 방식 도입 (예: JVM_OPTION Heap 메모리 설정). - 설정에 코드 주입: 빌드 과정에서 Python 스크립트 등을 주입하여 랜덤 값 선택 또는 동적 값 가져오기 기능 구현.
- 조건부 값 적용: 배열 내부에서 조건에 따라 다른 값을 적용하는 설정 기능 구현 (예: 클러스터에 따른
SPRING_PROFILES_INCLUDE변경). - 진화 가능한 구조: 요구사항 추가에 따라 유연하게 적응하고 확장 가능한 설정 인프라 구축.
Part 2: 배치 서버 설정
- Jenkins 활용 및 Job-DSL 플러그인 어댑터: GitOps 지원이 약한 Jenkins 환경에서 개발자의 반복 작업을 줄이기 위해 Groovy 코드로 Jenkins Job을 정의하는 Job-DSL 플러그인 어댑터 구현. 개발자는 간단한 함수 호출로 Java 버전, JVM 옵션, 모니터링 설정 등을 제어 가능.
- Dynamic Provisioning 인프라: 메모리 부족 문제를 해결하기 위해, 배치 실행 요청 시 동적으로 노드를 프로비저닝하고 사용 후 자동으로 종료하는 인프라 구축. 이를 통해 리소스 활용 극대화 및 비용 절감.
- 단일 업무 인터페이스 구축: 개발자는 애플리케이션 로직 개발에 집중 가능. 설정 관리 또한 개발자와 DevOps 간의 단일 인터페이스로 통합.
- 지속적인 진화: API 설정과 마찬가지로, 배치 설정 체계 역시 요구사항에 맞춰 진화하는 구조로 설계.
핵심 가치
- 설정도 코드처럼: 설정 또한 코드 개발처럼 바라보고 설계하여 중복을 제거하고 안정성을 높임.
- 개발자 경험 향상: 복잡한 인프라 설정을 추상화하여 개발자가 핵심 로직 개발에 집중할 수 있도록 지원.
- 안정성 및 확장성 확보: 단일 설정 체계로 수천 대의 서버를 일관되게 관리하고, 필요에 따라 동적으로 확장 가능한 인프라 구축.
- 지속적인 개선: 변화하는 요구사항에 맞춰 설정 인프라를 지속적으로 발전시키는 구조 설계.