배치/스케줄 작업
이 문서로 해결할 질문
- Consumer standalone job은 무엇이 있고 어떻게 실행하나요?
- 프로덕션(EC2)에서 배치 잡을 어떻게 실행하나요?
Always-on vs Job
| 유형 | 기동 | 용도 |
|---|---|---|
| Consumer (상시) | pnpm run start:consumer | Kafka 구독 |
| Standalone job | cron → CLI | 배치·ETL·KPI |
Standalone job은 NestFactory.createApplicationContext로 애플리케이션 컨텍스트를 만든 뒤 run-*.ts CLI로 실행하는 패턴을 따릅니다.
KPI 롤업
pnpm run kpi:rollup
# 또는
pnpm --filter consumer run job:kpi-rollup
| 항목 | 내용 |
|---|---|
| 구현 | server/consumer/.../kpi-rollup.service.ts |
| 입력 | MongoDB event_logs |
| 출력 | kpi_rollups 컬렉션 |
| KPI 예 | favorite CVR, recommendation latency, search CTR |
Observability 집계 파이프라인을 참고하세요.
Recipe Ingestion Jobs
| Job | CLI script | 역할 |
|---|---|---|
| fetch | job:recipe-ingestion-fetch | 공공데이터 수집 |
| parse-submit | job:recipe-ingestion-parse-submit | OpenAI Batch 파싱 요청 제출 |
| parse-retrieve | job:recipe-ingestion-parse-retrieve | 파싱 Batch 결과 조회 |
| persist | job:recipe-ingestion-persist | 수동 persist (운영) |
| embed-submit | job:recipe-ingestion-embed-submit | 임베딩 Batch 요청 제출 |
| embed-retrieve | job:recipe-ingestion-embed-retrieve | 임베딩 Batch 결과 적재 |
모노레포 루트에서는 아래 단축 명령을 사용할 수 있습니다.
pnpm run recipe-ingestion:fetch
pnpm run recipe-ingestion:parse-submit
pnpm run recipe-ingestion:parse-retrieve
pnpm run recipe-ingestion:embed-submit
pnpm run recipe-ingestion:embed-retrieve
단계별 상세는 레시피 수집 상세를 참고하세요.
로컬에서 Kafka 없이 실행할 때는 --no-kafka를 붙입니다. KafkaModule을 로드하지 않고 단계 간 트리거 발행을 생략합니다.
status 불일치로 단계가 skip될 때 운영 복구용으로 --force를 붙이면 대상 job 조회·상태 전환에서 status 검증을 생략합니다. --job-id 또는 --run-id와 함께 지정해야 합니다.
프로덕션 실행 (EC2 Docker)
프로덕션(EC2)에서는 consumer 이미지를 재사용한 일회성 컨테이너로 각 배치 잡을 실행합니다. docker/scripts/run-job.sh가 mealio-net 네트워크에 연결된 컨테이너를 생성하고 종료 후 자동 삭제합니다.
docker/scripts/run-job.sh kpi-rollup
docker/scripts/run-job.sh kpi-rollup 2026-05-22
docker/scripts/run-job.sh recipe-ingestion-fetch --fetch-limit 100
docker/scripts/run-job.sh recipe-ingestion-parse-retrieve
cron 등록 예시는 docker/scripts/consumer.cron.example을 참고하고, 실제 등록은 crontab consumer.cron으로 적용합니다.
| Task | cron 주기(예시) | 비고 |
|---|---|---|
| kpi-rollup | 매일 10:00 KST | 전일 EventLog 집계 |
| recipe-ingestion-fetch | 매일 11:00 KST | 공공데이터 수집 |
| recipe-ingestion-parse-submit | 매일 11:30 KST (fallback) | Kafka 트리거 유실 시 보완 |
| recipe-ingestion-parse-retrieve | 매 5분 | pending 없으면 no-op |
| recipe-ingestion-embed-submit | 매일 14:30 KST (fallback) | Kafka 트리거 유실 시 보완 |
| recipe-ingestion-embed-retrieve | 매 5분 | pending 없으면 no-op |
새 Job 추가 시
server/consumer/.../job 모듈과run-*.tsCLI를 추가합니다.server/consumer/package.json에 script를 등록합니다.docker/scripts/consumer.cron.example에 cron 항목을 추가합니다.- 관련 consumer 문서(아키텍처·배치·운영)를 갱신합니다.
- 필요하면 Observability 검증 시나리오를 추가합니다.