Skip to content

ADR-03: API와 Worker 서비스 분리

English Version

DateAuthorRepos
2024-12-17@KubrickCodeweb, collector

Context

문제 상황

장기 실행 분석 작업을 수행하는 시스템은 근본적인 아키텍처 과제에 직면한다: 실행 시간이 예측 불가능한 작업을 처리하면서 동시에 사용자에게 빠른 응답을 제공해야 하는 것.

분석 워크로드의 핵심 특성:

  1. 불확정적 실행 시간: 입력 크기에 따라 수초~수분까지 처리 시간 변동
  2. 리소스 집약적: 분석 중 높은 CPU, 메모리, I/O 사용
  3. 상충하는 요구사항: 사용자는 빠른 API 응답을 기대하지만 분석은 시간 소요

모놀리식의 딜레마

API와 분석을 단일 서비스에서 실행하면 여러 문제 발생:

문제영향
리소스 경쟁분석 작업이 API 핸들러의 CPU/메모리 점유
장애 전파Worker OOM 크래시 시 전체 서비스 다운
비효율적 스케일링분석만 필요해도 전체 서비스 확장 필요
배포 결합API 변경 시에도 분석 코드 재배포 필요
Cold Start 오버헤드바이너리 크기 증가로 시작 시간 지연

핵심 질문

반응성 있는 API 상호작용과 리소스 집약적 백그라운드 처리를 모두 요구하는 시스템을 어떻게 설계해야 하는가?

Decision

API 서비스와 Worker 서비스를 독립적으로 배포 가능한 단위로 분리한다.

아키텍처:

  • API 서비스: HTTP 요청 처리, 입력 검증, 작업 큐잉, 결과 반환
  • Worker 서비스: 큐잉된 작업 처리, 분석 수행, 결과 저장
  • 통신: 작업 분배용 메시지 큐
  • 데이터: 결과 저장용 공유 데이터베이스

Options Considered

Option A: 서비스 분리 (선택됨)

User → API Service → Queue → Worker Service → Database
                ↓                      ↓
           (enqueue)            (process & store)

장점:

  • API와 Worker 각각의 부하에 따른 독립적 스케일링
  • 장애 격리 - Worker 크래시가 API 가용성에 영향 없음
  • 리소스 최적화 - Worker에만 고메모리 인스턴스 할당 가능
  • 배포 독립성 - Worker 재배포 없이 API 업데이트 가능
  • 명확한 관심사 분리와 코드베이스

단점:

  • 운영 복잡성 - 두 서비스 모니터링 및 배포 필요
  • 통신 오버헤드 - 큐 시스템 의존성
  • 디버깅 복잡성 - 분산 시스템 추적 필요
  • 인프라 비용 - 큐 시스템(PostgreSQL)이 추가 의존성

Option B: 모놀리식 서비스

User → Single Service (API + Worker in-process)

장점:

  • 단순한 배포와 운영
  • 내부 통신 네트워크 오버헤드 없음
  • 단일 프로세스로 디버깅 용이
  • 낮은 인프라 비용 (단일 서비스)

단점:

  • 스케일링 비효율 - 전체 서비스 확장 필요
  • 장애 전파 - 분석 OOM이 API 종료 유발
  • 리소스 경쟁 - 분석이 API 응답 지연 유발
  • 배포 결합 - 모든 변경에 전체 재배포 필요
  • 컨테이너 이미지 크기 증가로 Cold Start 시간 증가

Option C: Serverless 함수

User → API Service → Serverless Function (analysis)

장점:

  • 자동 스케일링 내장
  • 사용량 기반 비용 모델
  • 서버 관리 불필요

단점:

  • Cold Start 지연이 분석에 문제 (네이티브 의존성)
  • 실행 시간 제한이 불충분할 수 있음
  • 네이티브 라이브러리의 복잡한 의존성 관리
  • 장기 실행 작업에 높은 호출당 비용

Consequences

Positive

  1. 독립적 스케일링

    • 높은 분석 수요 시 Worker 수평 확장
    • 사용자 트래픽에 따라 API 독립 확장
    • 필요한 곳에 리소스 할당으로 비용 최적화
  2. 장애 격리

    • Worker 메모리 고갈이 API 크래시 유발 안함
    • 분석 타임아웃이 API 응답 차단 안함
    • 전체 장애 대신 부분 성능 저하
  3. 기술적 최적화

    • Worker: 처리량 최적화 (배치 처리, 고메모리)
    • API: 지연 시간 최적화 (캐싱, 커넥션 풀링)
  4. 배포 유연성

    • Worker 코드 수정 없이 API 버그 핫픽스
    • API 다운타임 없이 분석 알고리즘 업데이트
    • 독립적 릴리스 주기

Negative

  1. 운영 오버헤드

    • 두 서비스 각각 모니터링, 로깅, 알림 필요
    • 여러 배포 파이프라인 유지보수
    • 환경 설정 동기화 필요
  2. 통신 의존성

    • 큐 시스템(PostgreSQL)이 핵심 인프라가 됨
    • 작업 처리에 네트워크 지연 추가
    • 메시지 전달 보장 설정 필요
  3. 일관성 문제

    • 여러 서비스에서의 DB 접근 조율 필요
    • 스키마 변경이 두 서비스에 영향
    • 공유 데이터 모델에 버전 관리 전략 필요

기술적 함의

측면함의
큐 시스템PostgreSQL 기반 큐 필요 (River)
데이터베이스 접근두 서비스 모두 DB 연결 관리 필요
모니터링서비스 간 디버깅을 위한 분산 추적
배포별도 CI/CD 파이프라인 또는 조율된 릴리스
설정공유 환경 변수 동기화 필요

Open-source test coverage insights