Skip to content

아키텍처

truloop-ai-server의 FastAPI + Celery 아키텍처, Service Layer 패턴, 요청 처리 흐름을 설명합니다.


아키텍처 다이어그램


아키텍처 패턴

Service Layer Pattern

비즈니스 로직을 서비스 클래스에 캡슐화하여 API 엔드포인트와 분리합니다.

계층책임
API RouteHTTP 요청 파싱, 응답 구성, DI
Service비즈니스 로직, AI 호출, 태스크 발행
ModelDB 접근 (SQLAlchemy ORM)
Schema입출력 데이터 검증 (Pydantic)

Repository Pattern

SQLAlchemy 모델을 통해 DB 접근을 추상화합니다. FastAPI의 Depends()를 통해 DB 세션을 주입합니다.

python
# FastAPI의 Depends() 기반 DI
@router.post("/generate")
async def generate(
    request: GenerateRequest,
    db: Session = Depends(get_db),
):
    service = ContentGenerationService(db)
    return await service.generate_content(...)

요청 처리 흐름

동기 흐름 (즉시 응답)

비동기 흐름 (Celery 태스크 + Junis 웹훅)


미들웨어 구성

미들웨어역할
SessionMiddleware세션 관리 (Admin UI)
MetricsMiddlewarePrometheus 요청 메트릭 수집
CORSMiddlewareCORS 설정

시작 프로세스


콘텐츠 생성 흐름

주요 서비스

서비스파일역할
ContentGenerationServicecontent_generation_service.py콘텐츠 생성 오케스트레이션 (태스크 발행, 미디어 선택, Junis 요청)
ContentTemplateServicecontent_template_service.py템플릿 CRUD
BestImageSelectorbest_image_selector.pyAI 기반 최적 이미지 선택 (토너먼트 방식, 이미지 URL 직접 전달)
JunisContentGeneratorjunis_content_generator.pyJunis AI API 연동 (웹훅 기반 비동기)
ImageAnalysisServiceimage_analysis_service.pyClaude 기반 이미지 분석/설명/태깅
MediaServicemedia/media_service.pyDB 조회 전용 미디어 서비스 (LoopMedia 읽기)
MediaUploadClientmedia/media_upload_client.py외부 Media API 업로드 클라이언트
NotificationServicenotification/notification_service.py알림 서비스 (현재 mock 구현)
ClaudeRateLimitercommon/rate_limiter.py동시 요청/분당 요청 Rate Limiter
TaskRegistrycore/task_registry.py중앙집중식 Celery Task 관리 (순환 import 방지)

콘텐츠 타입별 처리

콘텐츠 타입TemplateType EnumCelery Queue설명
일반/스토리storycontent_generation텍스트 기반 스토리 콘텐츠 (블록 JSON)
하이라이트highlight_default, highlight_style, highlight_tonehighlight_generation이미지 기반 하이라이트 비디오
포스터poster_style, poster_toneposter_generationAI 이미지 포스터

환경 설정

주요 환경변수
환경변수설명
DATABASE_URLPostgreSQL 연결 문자열 (postgresql+psycopg://)
DATABASE_POOL_SIZE / DATABASE_MAX_OVERFLOWDB 커넥션 풀 설정 (기본: 10/20)
VALKEY_URL / VALKEY_HOST + VALKEY_PORTRedis/Valkey 연결
OPENROUTER_API_KEYOpenRouter API 키 (Claude LLM 호출)
JUNIS_API_KEY / JUNIS_DOMAINJunis AI 콘텐츠 생성 서비스
MEDIA_API_BASE_URLMedia API 업로드 엔드포인트
AWS_*AWS 자격 증명 (S3)
S3_BUCKETS3 버킷 이름
API_BASE_PATHAPI 경로 prefix (기본: 빈 문자열)
API_BASE_URL웹훅 콜백 URL 생성용 (Junis AI)
ENV환경 모드 (development/staging/production)
SENTRY_DSNSentry 에러 추적
ADMIN_SECRET_KEYAdmin 세션 비밀 키
REPLICATE_API_TOKENReplicate API 키

헬스체크

/health 엔드포인트에서 DB와 Redis 연결 상태를 동시에 확인합니다:

  • 각 체크에 1.5초 타임아웃 적용
  • asyncio.gather()로 병렬 실행
  • 모든 체크 통과 시 200 OK, 하나라도 실패 시 503 Service Unavailable
json
{
    "status": "ready",
    "checks": {
        "database": { "status": "healthy" },
        "redis": { "status": "healthy" }
    },
    "response_time_ms": 45.2
}

배포

ECS Fargate (ARM64)

FastAPI 서버와 Celery Worker 모두 ECS Fargate ARM64 (Graviton) 환경에서 실행됩니다.

항목FastAPICelery Worker
아키텍처ARM64 (Graviton)ARM64 (Graviton)
CPU512 (0.5 vCPU)512 (0.5 vCPU)
메모리1024 MB1024 MB
Desired CountDev: 1, Prod: 2Dev: 1, Prod: 2

Docker 빌드

bash
docker buildx build --platform linux/arm64 -t truloop-ai-server:latest .

Celery Worker 설정

환경변수기본값설명
CELERY_CONCURRENCY2워커 동시 처리 수 (0.5 vCPU/1GB 기준)
CELERY_PREFETCH_MULTIPLIER1워커당 프리페치 태스크 수
CELERY_MAX_TASKS_PER_CHILD1000워커 프로세스 재시작 주기

정보

CELERY_CONCURRENCY는 Pulumi ESC에서 환경별로 재정의할 수 있습니다. I/O-bound 작업이므로 CPU보다 메모리가 제약 요소이며, 워커당 약 80-100MB 메모리를 사용합니다.


변경 이력

날짜내용
2026-03-11ECS Fargate ARM64 (Graviton) 전환, 리소스 최적화 (CPU 2048→512, Memory 4096→1024), BestImageSelector 이미지 URL 직접 전달 반영
2026-03-10최초 작성