portal-backend 포트폴리오 노트

메인 인덱스 | CCG-Platform | 오버뷰 | GitHub

이 문서는 제가 portal-backend 레포를 조금 더 길게 설명하려고 남긴 심층 메모입니다. 빠르게 훑어보실 때는 오버뷰부터 보시고, 구현 판단이나 한계까지 보고 싶으실 때 이 문서로 내려오시면 됩니다.

왜 이 레포를 먼저 설명하는가

portal-backend는 프로덕션 백엔드를 어떤 시각으로 읽고 설명하는지 보여드리기 좋은 레포입니다. 인증, 결제, 워크스페이스 라이프사이클, 관리자 패널, 비동기 작업이 한 곳에 모여 있어서 운영 백엔드의 구조를 정리하기에 적합합니다.

제가 맡은 범위

  • CCGP 팀장 역할
  • Front와 DB 설계를 제외한 대부분의 구현
  • 운영 백엔드, Pod 관리 흐름, 인프라 연결부 중심 구현

이 레포에서 드러나는 점

  • 단순 CRUD 서버가 아니라 운영 백엔드 전체를 설계하고 구현하는 관점을 갖고 있다는 점
  • Kubernetes 기반 워크스페이스 플랫폼에서 백엔드가 어떤 책임을 가져야 하는지 설명할 수 있다는 점
  • 구현 결과뿐 아니라 남은 제약의 원인도 함께 추적했다는 점

프로젝트 개요

이 문서는 제가 portal-backend를 포트폴리오에서 설명할 때 쓰는 기준 정리입니다. portal-backend는 CCGP (Cloud Container Gaming Platform)의 핵심 백엔드 시스템으로, FastAPI 기반으로 구축되었고 컨테이너 게이밍 워크스페이스 관리, 결제 처리, 사용자 인증 같은 주요 기능을 맡고 있습니다.


1. 기능 (Functions)

1.1 자동-발견 기반 API 라우트 시스템

  • 동적 라우트 마운팅: src/server.pyget_sub_applications_mount() 함수는 파일 시스템을 스캔하여 자동으로 API 버전(v1, v2 등)과 서비스 라우트를 탐색하고 마운트합니다. 새로운 API 모듈을 추가할 때 __init__.pyrouter만 정의하면 별도의 서버 재시작 없이 자동으로 인식됩니다.

  • 서비스 자동 등록: src/application/api/v1/__init__.pyservice 폴터의 각 모듈에서 라우터를 자동으로 수집하여 메인 라우터에 포함시킵니다. 이를 통해 auth, workspace, transaction, product 등의 서비스를 선언적으로 등록할 수 있습니다.

  • 환경별 라우트 제어: __EXCLUDING_ROUTE__ 플래그를 통해 특정 환경(예: production)에서는 특정 라우트를 제외할 수 있는 유연한 구조를 제공합니다. 이는 개발 환경에서만 필요한 디버그 엔드포인트를 관리하는 데 유용합니다.

1.2 사용자 인증 및 권한 관리 시스템

  • fastapi-users 통합 인증: src/application/api/v1/service/auth/auth_service.py는 fastapi-users 라이브러리를 확장하여 JWT 기반 인증, OAuth2, 이메일 검증, 비밀번호 재설정 등의 기능을 제공합니다. UserManager 클래스는 각 사용자 액션(등록, 로그인, 검증 등)에 대한 후처리 로직을 커스터마이징할 수 있는 8개의 라이프사이클 메서드를 구현했습니다.

  • Redis 기반 세션 관리: src/application/api/dependencies.py는 Redis를 활용한 세션 전략(RedisStrategy)을 구현하여 토큰 블랙리스팅, 세션 만료, 분산 환경에서의 세션 공유를 지원합니다. 토큰의 유효 기간은 환경설정에서 동적으로 조정 가능합니다.

  • 역할 기반 접근 제어: current_active_user, current_superuser 등의 FastAPI 의존성 주입 함수를 통해 엔드포인트별로 세분화된 권한 체크를 수행할 수 있습니다. 검증된 사용자, 활성 사용자, 관리자 등 다양한 권한 레벨을 지원합니다.

1.3 컨테이너 워크스페이스 라이프사이클 관리

  • Pod Controller 연동: src/application/api/v1/service/workspace/workspace_service.py는 Pod Controller 서비스(POD_CONTROLLER_SERVICE)와 HTTP 통신하여 컨테이너 워크스페이스의 생성, 조회, 삭제를 관리합니다. aiohttp를 사용한 비동기 HTTP 클라이언트로 외부 서비스 호출의 성능을 최적화했습니다.

  • 워크스페이스 메타데이터 관리: 데이터베이스에는 워크스페이스의 대여 정보(ContainerRentals)를 저장하고, 실제 컨테이너 실행은 Pod Controller에 위임하는 하이브리드 아키텍처를 채택했습니다. 이를 통해 비즈니스 로직과 인프라 관리를 분리했습니다.

  • 에러 처리 및 복구: _handle_response() 헬퍼 함수를 통해 Pod Controller의 응답을 일관되게 처리하며, 2xx 응답과 에러 응답을 구분하여 적절한 예외를 발생시킵니다. 이는 API의 안정성과 클라이언트에게 명확한 에러 메시지를 제공합니다.

1.4 분당 과금 기반 결제 시스템

  • 실시간 과금 처리: src/infrastructure/celery/tasks/process_rental_billing_task.py는 1분마다 실행되는 Celery 태스크로, 활성화된 대여 건의 과금을 자동으로 처리합니다. 사용자 잔액에서 분당 요금(price_per_min)을 차감하고, 잔액 부족 시 자동으로 워크스페이스를 종료합니다.

  • 트랜잭션 이력 관리: 모든 과금 내역은 Transactions 테이블에 기록되어 투명한 결제 이력을 제공합니다. 과금(charge), 충전(deposit) 등 다양한 트랜잭션 타입을 지원하며, 특정 대여 건과 연결된 과금 내역을 추적할 수 있습니다.

  • 비동기 알림 시스템: send_mail_task Celery 태스크를 통해 비밀번호 변경, 이메일 검증, 환영 메일 등의 이메일 알림을 비동기로 발송합니다. 이는 메인 API 응답 시간에 영향을 주지 않으면서도 사용자 경험을 향상시킵니다.

1.5 제품 카탈로그 관리

  • 유연한 리소스 정의: ContainerResources 모델은 JSON 타입의 resource 필드를 통해 CPU, GPU, 메모리 등의 사양을 유연하게 정의할 수 있습니다. 이는 다양한 컨테이너 스펙을 하나의 테이블에서 관리할 수 있게 해줍니다.

  • 소프트 삭제 지원: delete_product()는 실제 레코드를 삭제하는 대신 deleted_at 필드를 업데이트하는 소프트 삭제를 수행합니다. 이는 실수로 삭제된 데이터를 복구하거나, 삭제 이력을 유지해야 하는 감사 요구사항을 충족합니다.

  • 페이징 및 필터링: get_list_products()는 offset/limit 기반 페이징과 다중 필터링을 지원하여 대용량 제품 목록을 효율적으로 조회할 수 있습니다.

1.6 관리자 패널 (Starlette Admin)

  • 자동 관리 인터페이스: src/utils/starlette_admin/admin_panel.py는 Starlette Admin을 활용하여 데이터베이스 모델(User, ContainerResources, ContainerRentals, Transactions)에 대한 CRUD 인터페이스를 자동으로 생성합니다. 커스텀 뷰(UserView, ProductView 등)를 통해 특정 모델의 표시 방식을 조정할 수 있습니다.

  • 통합 인증: CustomAuthProvider를 통해 관리자 패널에 대한 접근을 제어하며, 일반 사용자 인증 시스템과 통합되어 있습니다.

  • 외부 링크 통합: Swagger UI, ReDoc 등의 API 문서 링크를 관리자 패널에 직접 포함하여 개발자 경험을 향상시킵니다.


2. 특징 (Characteristics)

2.1 계층형 아키텍처 및 관심사 분리

  • 명확한 레이어 구분:

    • Presentation Layer: application/api/ - FastAPI 라우트와 스키마 정의
    • Service Layer: application/api/v1/service/*/*_service.py` - 비즈니스 로직
    • Repository Layer: crud/base_crud.py - 데이터 접근 로직
    • Infrastructure Layer: infrastructure/ - 데이터베이스, Celery, Redis, 외부 API 연동
  • 제네릭 CRUD 구현: BaseRepository 클래스는 Python 제네릭(Generic[ModelType])을 활용하여 모든 모델에 대해 동일한 CRUD 인터페이스를 제공합니다. async_get_list(), async_create(), async_update() 등의 메서드는 타입 안전성을 보장하면서 코드 중복을 제거했습니다.

  • 동기/비동기 듀얼 지원: BaseRepository는 동기 메서드(get_list, create, update)와 비동기 메서드(async_get_list, async_create, async_update)를 모두 제공하여, Celery 워커(동기)와 FastAPI 엔드포인트(비동기) 모두에서 재사용할 수 있습니다.

2.2 고급 로깅 및 모니터링 시스템

  • Loguru 기반 구조화 로깅: src/core/logger.py는 표준 logging 모듈을 Loguru로 인터셉트하여 일관된 로그 형식과 색상화된 콘솔 출력을 제공합니다. InterceptHandler를 통해 기존 라이브러리들의 로그도 Loguru로 통합합니다.

  • 파일 기반 로그 관리: 로거 이름별로 별도의 로그 파일을 생성하며, 파일 크기 기반 로테이션(10MB)과 백업 개수 제한(5개)을 통해 디스크 공간을 효율적으로 관리합니다. 로그 파일은 gzip으로 압축되어 저장됩니다.

  • Apprise 통합 알림: ERROR 레벨 이상의 로그는 자동으로 Apprise를 통해 외부 알림 채널(Discord, Slack, Telegram 등)로 전송될 수 있습니다. 이는 운영 환경에서 치명적인 문제를 즉시 인지할 수 있게 해줍니다.

  • 요청/응답 로깅 미들웨어: LoggingMiddleware는 모든 HTTP 요청의 메서드, 경로, 상태 코드, 실행 시간을 자동으로 로깅하여 성능 모니터링과 디버깅을 용이하게 합니다.

  • 선택적 프로파일링: YappiProfileMiddleware는 환경변수(YAPPI_PROFILE_ENABLE)에 따라 조건부로 활성화되어, 성능 병목 지점을 식별할 수 있는 상세한 프로파일링 데이터를 수집합니다.

2.3 환경별 설정 관리

  • Pydantic Settings 기반 구성: src/core/config/app_config.py는 Pydantic BaseSettings를 활용하여 환경변수에서 설정을 로드하며, 타입 검증과 기본값 제공을 통해 설정 오류를 런타임에 방지합니다.

  • pyproject.toml 연동: 애플리케이션 메타데이터(이름, 버전, 설명)는 pyproject.toml에서 동적으로 로드하여 단일 소스 원칙을 준수합니다. 환경변수로 오버라이드 가능하여 유연한 배포를 지원합니다.

  • 데이터베이스 Read/Write 분리: dependencies.py에서 writer와 reader 데이터베이스 엔진을 분리하여 향후 읽기/쓰기 분리 아키텍처로의 확장을 준비했습니다.

  • 환경별 문서 노출 제어: Production 환경에서는 Swagger UI, ReDoc, OpenAPI JSON 엔드포인트를 비활성화하여 API 스키마 노출을 방지하고 보안을 강화합니다.

2.4 Celery 기반 비동기 작업 처리

  • 주기적 과금 작업: schedule_billing_checks_task는 60초 간격으로 실행되는 Celery Beat 스케줄러를 통해 모든 활성 대여 건에 대한 과금을 체크하고 필요 시 process_rental_billing 태스크를 큐에 추가합니다.

  • 데이터베이스 트랜잭션 관리: create_sync_session_context 컨텍스트 매니저는 Celery 태스크에서 데이터베이스 세션의 생명주기를 관리하며, 자동 커밋/롤백을 보장하여 데이터 일관성을 유지합니다.

  • SELECT FOR UPDATE 락: 과금 처리 시 with_for_update()를 사용하여 동시성 문제를 방지하고, 동일한 대여 건에 대한 중복 과금을 막습니다.

2.5 타입 안전성 및 코드 품질

  • Pydantic V2 스키마: 모든 API 요청/응답은 Pydantic V2 기반의 스키마로 정의되어 런타임 타입 검증과 자동 문서화를 제공합니다. model_validate()model_dump() 메서드를 통해 일관된 직렬화/역직렬화를 수행합니다.

  • SQLAlchemy 2.0 ORM: Mapped 타입 힌트와 mapped_column을 사용하여 모델 정의에 타입 안전성을 적용했습니다. 관계 설정(relationship)도 타입 힌트를 통해 IDE 자동완성을 지원합니다.

  • Pre-commit 훅: pyproject.toml에 정의된 개발 의존성(isort, ruff, bandit, pylint)과 pre-commit 훅을 통해 코드 포맷팅, 보안 검사, 린팅을 자동화하여 코드 품질을 유지합니다.

2.6 예외 처리 및 에러 응답 표준화

  • 커스텀 예외 계층: APIClientError 예외 클래스는 외부 API 호출 실패 시 일관된 에러 정보(status_code, detail)를 포함하여 상위 레이어에서 적절한 HTTP 응답으로 변환할 수 있게 합니다.

  • 전역 예외 핸들러: FastAPI 앱 레벨의 @app.exception_handler(Exception)는 처리되지 않은 모든 예외를 잡아 500 응답으로 변환하고 로깅하여 서버 크래시를 방지합니다.

  • HTTP 상태 코드 활용: _handle_response()는 FastAPI의 status 모듈 상수(HTTP_204_NO_CONTENT, HTTP_500_INTERNAL_SERVER_ERROR 등)를 사용하여 의미 있는 HTTP 응답을 생성합니다.


3. 부족한 점 (Limitations)

3.1 테스트 인프라 부재

  • 테스트 코드 미존재: 프로젝트 전체에 pytest나 unittest 기반의 테스트 코드가 없습니다. tests/ 디렉토리가 존재하지 않으며, 단위 테스트, 통합 테스트, E2E 테스트 모두 부재합니다. 이는 리팩토링 시 회귀 버그 발생 위험을 높이고, CI/CD 파이프라인에서 품질 게이트를 설정할 수 없습니다.

  • 테스트용 DB/Redis 설정 없음: 테스트 환경을 위한 격리된 데이터베이스나 mock Redis 설정이 없어, 로컬 개발 환경의 데이터를 오염시킬 위험이 있습니다.

  • 의존성 주입 테스트 미흡: FastAPI의 Depends를 사용하는 의존성 주입 로직을 테스트하기 위한 fixture나 override 메커니즘이 구축되지 않았습니다.

3.2 API 문서화 및 버전 관리 미흡

  • OpenAPI 스키마 불완전: Pydantic 스키마는 정의되어 있으나, 엔드포인트별로 summary, description, response_model 등의 FastAPI 문서화 데코레이터가 일관되게 적용되지 않았습니다. 일부 라우트에는 태그만 있고 상세 설명이 부족합니다.

  • API 버전 관리 전략 부재: 현재 v1 API만 존재하지만, 향후 v2로의 마이그레이션을 위한 전략(URI versioning vs Header versioning, deprecation 정책 등)이 문서화되지 않았습니다.

  • 스키마 문서화 누락: Pydantic 스키마의 필드별 Field(description=...) 정의가 거의 없어, Swagger UI에서 필드의 의미를 파악하기 어렵습니다.

3.3 에러 처리 및 복구 메커니즘 취약점

  • 세분화된 예외 부재: 현재는 APIClientError 하나의 예외 클래스로 대부분의 에러를 처리하고 있어, 클라이언트가 에러 유형에 따라 다른 처리를 하기 어렵습니다. 예: ValidationError, NotFoundError, ConflictError 등의 세분화가 필요합니다.

  • 재시도 로직 없음: Pod Controller나 SMTP 서버 등 외부 서비스 호출 시 네트워크 일시 장애에 대응하는 exponential backoff 재시도 로직이 없습니다. requests.delete() 호출이 실패하면 해당 워크스페이스는 과금은 멈췄지만 실제로는 종료되지 않는 불일치 상태가 발생할 수 있습니다.

  • 트랜잭션 롤백 검증 부족: Celery 태스크에서 예외 발생 시 롤백은 수행되지만, 이미 외부 서비스에 호출한 작업(Pod 삭제 등)은 되돌릴 수 없는 eventual consistency 문제가 있습니다.

3.4 보안 강화 필요

  • Rate Limiting 부재: API 엔드포인트에 대한 요청 빈도 제한(rate limiting)이 구현되어 있지 않아, brute-force 공격이나 DDoS에 취약합니다. 로그인 엔드포인트에 대한 보호가 특히 필요합니다.

  • CORS 설정 완화: 현재 CORS 설정(allow_origin_regex=r"https?://(.+\.)?ccgp\.dev")은 서브도메인을 허용하지만, allow_credentials=True와 함께 사용될 때 보안 위험이 있습니다. 정확한 origin 목록을 명시하는 것이 더 안전합니다.

  • SQL Injection 가능성: _apply_filters() 메서드에서 사용자 입력을 직접 getattr로 변환하여 사용하는데, 이는 모델 속성만 허용하는 화이트리스트 검증이 없어 잠재적인 보안 위험이 있을 수 있습니다.

  • 비밀번호 정책 미흡: fastapi-users의 기본 설정을 사용하므로, 최소 길이, 복잡도 요구사항, 이전 비밀번호 재사용 방지 등의 정책이 없습니다.

3.5 확장성 및 운영 한계

  • 단일 데이터베이스 의존: 현재는 단일 PostgreSQL 인스턴스를 사용하며, read replica나 샤딩 전략이 없어 데이터베이스가 병목이 될 수 있습니다.

  • Celery Worker 모니터링 제한: Flower가 의존성에 포함되어 있으나, 프로덕션 환경에서의 worker health check, dead letter queue, 태스크 재처리 전략 등이 구현되지 않았습니다.

  • 로그 집계 부재: 파일 기반 로깅만 제공하며, ELK 스택이나 CloudWatch 같은 중앙 집계 시스템으로의 연동을 위한 구조화된 로그(JSON 포맷) 출력이 없습니다.

3.6 실시간 기능 부재

  • WebSocket 미지원: 현재 모든 통신은 HTTP 요청/응답 기반으로, 실시간 알림(워크스페이스 상태 변경, 잔액 부족 경고 등)을 위한 WebSocket이나 Server-Sent Events(SSE)가 구현되어 있지 않습니다.

  • 웹훅 시스템 없음: 외부 시스템(Pod Controller, 결제 게이트웨이)으로부터의 이벤트 수신을 위한 웹훅 엔드포인트가 없어, 폴링 방식으로 상태를 확인해야 합니다.


4. 개선 방향 (Improvements)

4.1 테스트 인프라 구축

  • 단위 테스트 스위트 도입: pytest와 pytest-asyncio를 사용하여 서비스 레이어와 CRUD 레이어에 대한 단위 테스트를 작성합니다. pytest-mock으로 외부 의존성(Pod Controller, SMTP)을 모킹하고, pytest-cov로 80% 이상의 커버리지를 목표로 합니다.

  • 통합 테스트 환경: testcontainers 라이브러리를 사용하여 테스트용 PostgreSQL과 Redis 컨테이너를 자동으로 생성하는 fixture를 구축합니다. conftest.py에 공통 설정을 정의하여 모든 테스트에서 재사용합니다.

  • API 엔드포인트 테스트: FastAPI의 TestClientAsyncClient를 사용하여 각 엔드포인트의 성공/실패 시나리오를 테스트합니다. 인증이 필요한 엔드포인트는 dependency_overrides를 사용하여 테스트용 사용자로 주입합니다.

  • Celery 태스크 테스트: celery.contrib.testing을 사용하여 Celery 태스크의 비즈니스 로직을 테스트하고, 모킹을 통해 데이터베이스와 외부 API 호출을 검증합니다.

4.2 API 문서화 및 버전 관리 개선

  • OpenAPI 스키마 강화: 모든 Pydantic 스키마에 Field(description=..., example=...)를 추가하여 Swagger UI에서 필드의 의미와 예시 값을 명확히 표시합니다. 엔드포인트 데코레이터에 summary, description, response_description을 추가합니다.

  • API 버전 관리 전략 수립: URI 기반 버전 관리(/api/v1/, /api/v2/)를 유지하되, 하위 호환성을 깨는 변경 시 명확한 deprecation 정책을 문서화합니다. X-API-Version 헤더를 통한 클라이언트 버전 협상도 고려합니다.

  • API 변경 로그 관리: CHANGELOG.mdAPI_CHANGES.md를 유지하여 버전 간 변경 사항을 문서화하고, 마이그레이션 가이드를 제공합니다.

4.3 에러 처리 및 복구 메커니즘 강화

  • 예외 계층 구조화: src/core/exceptions.py에 다음과 같은 예외 클래스를 추가합니다:

    • NotFoundError (404)
    • ValidationError (422)
    • ConflictError (409)
    • ExternalServiceError (503)
    • InsufficientBalanceError (402)
  • 재시도 로직 구현: tenacity 라이브러리를 사용하여 Pod Controller 호출과 SMTP 발송에 exponential backoff 재시도 로직을 추가합니다. 일시적인 네트워크 오류에 대한 복원력을 높입니다.

  • Dead Letter Queue: Celery 태스크 실패 시 자동 재시도 횟수를 제한하고, 최종 실패한 태스크는 dead letter queue에 저장하여 수동 조사가 가능하게 합니다.

  • Saga 패턴 적용: 워크스페이스 생성 → 과금 시작의 분산 트랜잭션에 Saga 패턴을 적용하여, 각 단계별 보상 작업(compensating action)을 정의하고 eventual consistency를 관리합니다.

4.4 보안 강화

  • Rate Limiting 구현: slowapi 라이브러리를 사용하여 IP 기반 및 사용자 기반 rate limiting을 구현합니다. 특히 로그인, 비밀번호 재설정 엔드포인트에 strict limit(5회/분)을 적용합니다.

  • CORS 설정 강화: 정확한 origin 목록을 config.ALLOWED_ORIGINS로 관리하고, production 환경에서는 와일드카드나 정규식 대신 명시적인 origin을 사용합니다.

  • 입력 검증 강화: _apply_filters()에 허용된 필드 목록(화이트리스트)을 추가하여, 존재하지 않는 모델 속성에 대한 접근을 방지합니다. Pydantic 스키마에서도 constr(), conint() 등으로 더 엄격한 검증을 적용합니다.

  • 보안 헤더 추가: secure.py 미들웨어를 추가하여 HSTS, CSP, X-Frame-Options, X-Content-Type-Options 등의 보안 헤더를 모든 응답에 포함시킵니다.

  • 비밀번호 정책 강화: fastapi-users의 password_helper를 커스터마이징하여 최소 12자, 대소문자+숫자+특수문자 포함, 이전 5개 비밀번호 재사용 방지 정책을 적용합니다.

4.5 확장성 및 성능 개선

  • 데이터베이스 Read Replica 활용: dependencies.py의 reader 엔진을 활성화하여 읽기 쿼리를 read replica로 분산시킵니다. 읽기 작업이 많은 엔드포인트(get_list_products, get_my_rentals)에서 get_read_async_session을 사용합니다.

  • 캐싱 레이어 도입: Redis를 활용하여 제품 목록, 사용자 세션 등의 데이터를 캐싱합니다. fastapi-cachecashews 라이브러리를 사용하여 데코레이터 기반 캐싱을 적용합니다.

  • 구조화된 로깅: JSON 포맷의 로그 출력을 지원하여 ELK 스택이나 Datadog으로의 연동을 용이하게 합니다. structlog나 Loguru의 JSON 포맷터를 사용합니다.

  • Health Check 엔드포인트 강화: 현재는 단순히 {"status": "OK"}를 반환하지만, 데이터베이스 연결, Redis 연결, Pod Controller 연결 상태를 포함한 상세한 health check를 구현합니다. Kubernetes 환경에서 readiness/liveness probe에 활용할 수 있습니다.

4.6 실시간 기능 추가

  • WebSocket 구현: FastAPI의 WebSocket 기능을 사용하여 실시간 알림 시스템을 구축합니다. 사용자별 웹소켓 연결을 관리하고, 워크스페이스 상태 변경, 잔액 부족 경고, 과금 알림 등을 실시간으로 푸시합니다.

  • 웹훅 시스템: 외부 시스템(Pod Controller)으로부터의 이벤트를 수신하는 웹훅 엔드포인트를 구현합니다. 워크스페이스 종료, 리소스 변경 등의 이벤트를 받아 실시간으로 데이터베이스를 업데이트합니다.

  • Server-Sent Events(SSE): 대체로 WebSocket이 더 유연하지만, 단방향 알림(서버→클라이언트)만 필요한 경우 SSE를 고려할 수 있습니다. HTTP 기반이므로 방화벽 친화적입니다.

4.7 운영 및 모니터링 개선

  • 메트릭 수집: prometheus-fastapi-instrumentator를 도입하여 요청 지연 시간, 에러율, 처리량 등의 메트릭을 Prometheus 형식으로 노출합니다. Grafana 대시보드와 연동하여 시각화합니다.

  • 분산 추적: OpenTelemetry를 사용하여 요청이 여러 서비스(Portal Backend → Pod Controller → Database)를 거치는 과정을 추적합니다. 성능 병목 지점과 에러 발생 지점을 시각적으로 파악할 수 있습니다.

  • Circuit Breaker 패턴: Pod Controller 같은 외부 서비스에 Circuit Breaker를 적용하여, 해당 서비스가 다운되었을 때 빠른 실패(fail-fast)하고, 복구되었을 때 자동으로 재시도하도록 합니다.

  • Graceful Shutdown: Uvicorn의 graceful shutdown을 활용하여, 진행 중인 요청을 완료한 후 프로세스를 종료하도록 합니다. Kubernetes 환경에서 rolling update 시 요청 손실을 방지합니다.

4.8 마이크로서비스 아키텍처 검토

  • 도메인 분리 평가: 현재는 모놀리식 구조이지만, 사용자 인증, 과금, 워크스페이스 관리를 별도 서비스로 분리하는 것을 장기적으로 검토합니다. 특히 과금 시스템은 독립적인 배포 주기와 확장이 필요할 수 있습니다.

  • API Gateway 도입: 마이크로서비스로 전환 시 Kong, Ambassador 등의 API Gateway를 도입하여 인증, rate limiting, 라우팅을 중앙에서 관리합니다.

  • 이벤트 기반 아키텍처: Apache Kafka나 AWS SNS/SQS를 사용하여 서비스 간 느슨한 결합을 구현합니다. 예: “워크스페이스 생성됨” 이벤트를 발행하면 과금 서비스가 이를 구독하여 과금을 시작합니다.


결론

portal-backend는 FastAPI와 SQLAlchemy 2.0을 기반으로 한 현재 사용한 Python 백엔드 아키텍처를 잘 다루는 프로젝트입니다. 자동 라우트 디스커버리, 계층형 아키텍처, 제네릭 CRUD, Celery 기반 비동기 처리 등 다양한 고급 패턴을 적절히 활용하고 있습니다.

그러나 테스트 부재, API 문서화 미흡, rate limiting 부재 등 프로덕션 환경에서 필수적인 요소들이 누락되어 있습니다. 특히 테스트 인프라 구축과 보안 강화는 즉시 진행해야 할 우선순위 높은 작업입니다.

향후 WebSocket 기반 실시간 기능, 구조화된 로깅, 메트릭 수집 등을 추가하면 더욱 완성도 높은 클라우드 게이밍 플랫폼 백엔드를 구축할 수 있을 것입니다.