TIL - 20260703

juni·2026년 7월 3일

TIL

목록 보기
392/470

0703 백엔드 실무 심화 (10/N): 배치 작업, 스케줄러와 Cron 운영 설계


✅ 1. 배치 작업이란 무엇인가?

  • 배치 작업(Batch Job)은 사용자의 실시간 요청과 별개로, 일정한 시간이나 조건에 따라 묶음으로 처리하는 작업입니다.
  • 웹서비스에서는 매일 통계 집계, 오래된 파일 삭제, 실패 알림 재처리, EP 파일 생성, 백업, 상태 자동 변경 같은 작업을 배치로 처리합니다.
  • 사용자가 버튼을 눌러 바로 실행하는 API와 달리, 배치 작업은 보통 서버가 정해진 시간에 자동으로 실행합니다.
실시간 API:
사용자 요청 → 즉시 처리 → 응답 반환

배치 작업:
정해진 시간 → 서버가 자동 실행 → 결과 저장

➕ 1-1. 배치 작업이 필요한 이유

  • 반복 업무 자동화

    • 매일 해야 하는 통계 집계, 파일 정리, 상태 변경을 자동화할 수 있습니다.
  • 운영자 실수 감소

    • 사람이 수동으로 처리하면 누락되거나 늦어질 수 있는 작업을 안정적으로 실행할 수 있습니다.
  • 서버 부하 분산

    • 무거운 작업을 트래픽이 적은 새벽 시간에 실행할 수 있습니다.
  • 운영 데이터 품질 유지

    • 오래된 임시 데이터, 실패 작업, 만료된 토큰 등을 정리할 수 있습니다.
예시:
매일 새벽 3시
  ↓
전날 상담 신청 통계 집계
  ↓
관리자 대시보드용 summary 테이블 업데이트

✅ 2. Scheduler와 Cron

  • Scheduler는 정해진 시간이나 주기에 따라 작업을 실행하는 구조입니다.
  • Cron은 리눅스와 서버 운영에서 많이 쓰이는 스케줄 표현 방식입니다.
  • NestJS에서도 @nestjs/schedule을 사용하면 Cron 표현식으로 정기 작업을 만들 수 있습니다.

➕ 2-1. Cron 표현식 예시

매분 실행:
* * * * *

매일 새벽 3시 실행:
0 3 * * *

매주 월요일 새벽 4시 실행:
0 4 * * 1

매월 1일 새벽 2시 실행:
0 2 1 * *

➕ 2-2. Cron 필드 구조

* * * * *
│ │ │ │ │
│ │ │ │ └─ 요일
│ │ │ └─── 월
│ │ └───── 일
│ └─────── 시
└───────── 분
  • Cron은 편하지만 잘못 설정하면 너무 자주 실행되거나 전혀 실행되지 않을 수 있습니다.
  • 운영 작업에는 실행 시간, 타임존, 중복 실행 방지까지 함께 고려해야 합니다.

✅ 3. 배치 작업이 적합한 기능

➕ 3-1. 통계 집계

  • 일별 상담 신청 수
  • 유입경로별 전환 수
  • 상품별 신청 수
  • 관리자별 처리 수
  • 사전예약 신청 수
  • 일별 매출/정산 요약
매일 00:10
  ↓
전날 00:00 ~ 23:59 데이터 집계
  ↓
DailySummary 테이블 저장
  • 매번 관리자 대시보드에서 원본 테이블을 직접 집계하면 느릴 수 있습니다.
  • 배치로 요약 테이블을 만들어두면 대시보드 응답 속도가 좋아집니다.

➕ 3-2. 실패 작업 재처리

  • 실패한 알림톡 재발송
  • 실패한 SMS 재발송
  • 실패한 CRM 연동 재시도
  • 실패한 광고 전환 API 재전송
  • 실패한 Webhook 재처리
매 10분마다
  ↓
FAILED 상태 중 재시도 가능한 작업 조회
  ↓
Queue에 재처리 Job 등록
  • 재처리할 수 있는 실패와 재처리하면 안 되는 실패를 구분해야 합니다.
  • 인증키 오류, 잘못된 템플릿 코드 같은 문제는 자동 재시도보다 설정 수정이 먼저입니다.

➕ 3-3. 만료/정리 작업

  • 만료된 인증번호 삭제
  • 오래된 임시 파일 삭제
  • 만료된 Export 파일 삭제
  • 오래된 Refresh Token 비활성화
  • 만료된 사전예약 이벤트 상태 변경
  • Soft Delete 데이터 아카이브
매일 새벽 4시
  ↓
7일 지난 Export 파일 조회
  ↓
S3 파일 삭제
  ↓
ExportJob 상태 EXPIRED 변경

➕ 3-4. 외부 제출 파일 생성

  • 네이버 EP 파일 생성
  • 당근 EP 파일 생성
  • 상품 피드 파일 생성
  • 가격/재고 동기화 파일 생성
  • 외부 광고 플랫폼용 CSV 생성
매일 새벽 2시
  ↓
노출 상품 조회
  ↓
EP XML/CSV 생성
  ↓
S3 업로드
  ↓
외부 플랫폼이 파일 수집
  • 상품 피드나 EP 파일은 수동으로 관리하면 실수가 많이 생깁니다.
  • 배치로 생성하고 생성 결과를 기록하는 것이 좋습니다.

✅ 4. 배치 작업과 Queue의 차이

  • 배치 작업과 Queue는 함께 쓰이지만 역할이 다릅니다.
구분배치 작업Queue
실행 기준시간/주기작업 등록
예시매일 새벽 통계 집계알림톡 발송 Job 처리
목적정기 실행비동기 처리
처리 방식정해진 시간에 실행Worker가 작업을 꺼내 처리

➕ 4-1. 같이 쓰는 구조

Cron Scheduler
  ↓
오늘 재처리할 실패 알림 조회
  ↓
Queue에 Job 등록
  ↓
Worker가 순차 처리
  • Cron이 모든 작업을 직접 처리하면 한 번에 부하가 몰릴 수 있습니다.
  • Cron은 “작업을 찾고 등록”하고, Queue Worker가 실제 처리를 담당하면 안정적입니다.

✅ 5. NestJS Schedule 기본 구조

  • NestJS에서는 @nestjs/schedule을 사용해 정기 작업을 만들 수 있습니다.
  • 보통 SchedulerModule이나 BatchModule을 따로 두고 관리하는 것이 좋습니다.

➕ 5-1. 설치 예시

npm install @nestjs/schedule

➕ 5-2. AppModule 설정 예시

import { ScheduleModule } from '@nestjs/schedule';

@Module({
  imports: [
    ScheduleModule.forRoot(),
  ],
})
export class AppModule {}

➕ 5-3. Cron Service 예시

@Injectable()
export class DailyStatsScheduler {
  constructor(
    private readonly dailyStatsService: DailyStatsService,
  ) {}

  @Cron('10 0 * * *', {
    timeZone: 'Asia/Seoul',
  })
  async handleDailyStats() {
    await this.dailyStatsService.aggregateYesterday();
  }
}
  • 매일 00:10에 전날 통계를 집계하는 예시입니다.
  • 한국 서비스라면 timeZone: 'Asia/Seoul'을 명확히 지정하는 것이 좋습니다.

✅ 6. 타임존 관리

  • 배치 작업에서 타임존은 매우 중요합니다.
  • 서버 시간이 UTC인데 한국 시간 기준으로 집계해야 하는 경우 날짜 범위가 어긋날 수 있습니다.

➕ 6-1. 문제 예시

한국 시간 2026-07-03 00:10
UTC 시간 2026-07-02 15:10

서버가 UTC 기준으로 어제 데이터를 집계하면:
한국 기준 날짜와 다를 수 있음

➕ 6-2. 실무 기준

  1. 서비스 기준 타임존을 정한다.
  2. Cron 실행 타임존을 명시한다.
  3. DB 저장 시간은 UTC 또는 명확한 기준으로 관리한다.
  4. 집계 기준 날짜는 서비스 타임존으로 계산한다.
  5. 관리자 화면에는 한국 시간으로 표시한다.
DB 저장:
UTC 권장

집계 기준:
Asia/Seoul 기준 날짜

관리자 표시:
Asia/Seoul 변환 표시
  • 날짜 범위 오류는 통계, 정산, 리포트에서 큰 문제를 만들 수 있습니다.
  • 배치 작업에서는 특히 시작 시간과 종료 시간을 정확하게 계산해야 합니다.

✅ 7. 일별 통계 집계 설계

  • 관리자 대시보드나 리포트에서 매번 원본 테이블을 조회해 집계하면 느려질 수 있습니다.
  • 일별 통계를 별도 테이블로 저장하면 조회가 빨라집니다.

➕ 7-1. DailyConsultSummary 모델 예시

model DailyConsultSummary {
  id            Int      @id @default(autoincrement())
  date          DateTime
  source        String?
  productId     Int?
  totalCount    Int      @default(0)
  pendingCount  Int      @default(0)
  doneCount     Int      @default(0)
  cancelCount   Int      @default(0)
  createdAt     DateTime @default(now())
  updatedAt     DateTime @updatedAt

  @@unique([date, source, productId])
  @@index([date])
  @@index([source, date])
}
  • 날짜, 유입경로, 상품별로 요약 데이터를 저장할 수 있습니다.
  • @@unique([date, source, productId])로 같은 기준의 중복 집계를 막습니다.

➕ 7-2. 집계 흐름

1. 어제 날짜 범위 계산
2. consults 테이블에서 source/productId별 집계
3. DailyConsultSummary에 upsert
4. 집계 성공 이력 저장
5. 관리자 대시보드에서 summary 테이블 조회

➕ 7-3. Prisma upsert 예시

await this.prisma.dailyConsultSummary.upsert({
  where: {
    date_source_productId: {
      date,
      source,
      productId,
    },
  },
  update: {
    totalCount,
    pendingCount,
    doneCount,
    cancelCount,
  },
  create: {
    date,
    source,
    productId,
    totalCount,
    pendingCount,
    doneCount,
    cancelCount,
  },
});
  • 같은 날짜의 집계를 다시 실행해도 중복 row가 생기지 않게 upsert를 사용합니다.
  • 배치 작업은 재실행 가능성을 고려해야 합니다.

✅ 8. 배치 작업 이력 테이블

  • 배치 작업은 실행됐는지, 성공했는지, 실패했는지 기록해야 합니다.
  • 기록이 없으면 작업이 정상적으로 돌았는지 알 수 없습니다.

➕ 8-1. BatchJobLog 모델 예시

model BatchJobLog {
  id           Int      @id @default(autoincrement())
  jobName      String
  status       String
  startedAt    DateTime
  endedAt      DateTime?
  durationMs   Int?
  targetDate   DateTime?
  processedCount Int?
  successCount Int?
  failCount    Int?
  errorMessage String?
  createdAt    DateTime @default(now())

  @@index([jobName, startedAt])
  @@index([status, startedAt])
}

➕ 8-2. 남기면 좋은 정보

  • 작업 이름
  • 시작 시간
  • 종료 시간
  • 실행 시간
  • 대상 날짜
  • 처리 건수
  • 성공 건수
  • 실패 건수
  • 에러 메시지
  • 실행 서버 또는 프로세스 정보
jobName=DAILY_CONSULT_SUMMARY
status=SUCCESS
targetDate=2026-07-02
processedCount=428
durationMs=1540
  • 배치 이력이 있으면 장애 대응과 운영 보고에 도움이 됩니다.

✅ 9. 중복 실행 방지

  • 배치 작업은 중복 실행을 조심해야 합니다.
  • 서버가 여러 대이거나, 배포 중 프로세스가 겹치거나, 작업 시간이 길어져 다음 실행과 겹치면 같은 작업이 두 번 실행될 수 있습니다.
매일 00:10 통계 집계 시작
  ↓
작업이 20분 걸림
  ↓
00:20에 같은 작업이 수동 실행됨
  ↓
같은 날짜 데이터가 중복 처리될 수 있음

➕ 9-1. 중복 실행 방지 방법

  1. DB에 실행 중 상태를 기록한다.
  2. 같은 jobName + targetDate 작업이 PROCESSING이면 실행하지 않는다.
  3. Redis Lock을 사용한다.
  4. Queue Job ID를 고정해서 중복 등록을 막는다.
  5. 결과 저장은 upsert로 멱등하게 만든다.

✅ 10. Redis Lock을 이용한 중복 실행 방지

  • Redis Lock은 특정 작업이 동시에 여러 번 실행되지 않도록 잠금을 거는 방식입니다.

➕ 10-1. 개념

배치 시작
  ↓
Redis에 lock key 생성 시도
  ↓
성공하면 작업 실행
  ↓
실패하면 이미 실행 중으로 판단하고 종료
  ↓
작업 완료 후 lock 해제

➕ 10-2. Lock Key 예시

lock:batch:daily-consult-summary:2026-07-02
lock:batch:ep-generate:naver
lock:batch:export-cleanup

➕ 10-3. 주의점

  • Lock에는 TTL을 반드시 설정해야 합니다.
  • 작업 중 서버가 죽어도 lock이 영원히 남으면 안 됩니다.
  • 작업 시간이 TTL보다 길어질 수 있다면 갱신 전략도 고려해야 합니다.
Lock TTL 없음:
서버 장애 시 lock이 영원히 남음

Lock TTL 있음:
일정 시간 후 자동 해제

✅ 11. 배치 작업의 멱등성

  • 멱등성은 같은 작업이 여러 번 실행되어도 결과가 중복되거나 꼬이지 않게 만드는 성질입니다.
  • 배치 작업은 재실행될 수 있기 때문에 멱등성이 중요합니다.

➕ 11-1. 나쁜 예시

매일 통계 집계 실행
  ↓
summary 테이블에 insert
  ↓
같은 날짜 작업 재실행
  ↓
같은 날짜 summary가 두 줄 생성

➕ 11-2. 좋은 예시

매일 통계 집계 실행
  ↓
date + source + productId 기준 upsert
  ↓
같은 날짜 작업 재실행
  ↓
기존 summary row 업데이트
  • 배치 작업은 언제든 재실행할 수 있게 만드는 것이 좋습니다.
  • 특히 실패 후 수동 재처리 기능을 만들려면 멱등성이 필수입니다.

✅ 12. EP 파일 생성 배치 설계

  • 온라인 판매몰에서는 네이버, 당근, 광고 플랫폼 등에 상품 피드 파일을 제공해야 할 수 있습니다.
  • EP 파일은 상품명, 가격, URL, 이미지 URL, 상태값 등을 일정 형식으로 생성합니다.

➕ 12-1. EP 생성 흐름

1. 노출 중인 상품 조회
2. 플랫폼별 필드로 변환
3. XML/CSV/TXT 파일 생성
4. S3 또는 서버 public 경로에 업로드
5. 생성 이력 저장
6. 외부 플랫폼이 파일 수집

➕ 12-2. EP 생성 시 주의할 점

  1. 상품 URL이 운영 도메인인지 확인한다.
  2. 이미지 URL이 외부에서 접근 가능한지 확인한다.
  3. 품절/비노출 상품이 포함되지 않게 한다.
  4. 가격, 지원금, 요금제 정보가 최신인지 확인한다.
  5. 특수문자와 줄바꿈을 정리한다.
  6. 기존 URL이 불필요하게 바뀌지 않게 한다.
  7. 생성 실패 시 이전 정상 파일을 유지할지 결정한다.
주의:
EP 파일 생성 실패 후 빈 파일을 업로드하면
외부 플랫폼에서 전체 상품이 사라진 것처럼 인식할 수 있음
  • EP 파일은 실패했을 때 기존 파일을 덮어쓰지 않는 전략이 중요합니다.

✅ 13. 오래된 Export 파일 정리 배치

  • 엑셀 다운로드 파일은 오래 보관할 필요가 없는 경우가 많습니다.
  • 개인정보가 포함될 수 있으므로 일정 기간 후 삭제하는 것이 좋습니다.

➕ 13-1. 정리 흐름

1. expiresAt이 지난 ExportJob 조회
2. S3 fileKey 확인
3. S3 파일 삭제
4. ExportJob 상태 EXPIRED 변경
5. 정리 결과 로그 저장

➕ 13-2. Service 예시

async cleanupExpiredExports() {
  const expiredJobs = await this.prisma.exportJob.findMany({
    where: {
      status: 'COMPLETED',
      expiresAt: {
        lt: new Date(),
      },
    },
    select: {
      id: true,
      fileKey: true,
    },
    take: 100,
  });

  for (const job of expiredJobs) {
    if (job.fileKey) {
      await this.s3Service.deleteObject(job.fileKey);
    }

    await this.prisma.exportJob.update({
      where: {
        id: job.id,
      },
      data: {
        status: 'EXPIRED',
      },
    });
  }

  return {
    processedCount: expiredJobs.length,
  };
}
  • 한 번에 너무 많은 파일을 지우지 않도록 take로 제한할 수 있습니다.
  • S3 삭제 실패와 DB 상태 변경 실패를 어떻게 처리할지 고민해야 합니다.

✅ 14. 실패 알림 재처리 배치

  • 알림톡/SMS 발송 실패 건 중 재시도 가능한 것만 다시 Queue에 넣을 수 있습니다.

➕ 14-1. 재처리 대상 기준

재처리 가능:
TIMEOUT
NETWORK_ERROR
PROVIDER_500
RATE_LIMIT

재처리 제외:
INVALID_PHONE
INVALID_TEMPLATE
AUTH_FAILED
PERMISSION_DENIED

➕ 14-2. 재처리 흐름

1. FAILED 상태 알림 로그 조회
2. retryable=true인 것만 필터
3. attempts < maxAttempts 확인
4. Queue에 재발송 Job 등록
5. attempts 증가 또는 RETRYING 상태 변경
6. 결과 이력 저장
  • 재시도 가능 여부를 에러 코드 기준으로 나누는 것이 좋습니다.
  • 모든 실패를 무조건 재시도하면 비용과 장애가 커질 수 있습니다.

✅ 15. 배치 작업과 알림

  • 중요한 배치 작업은 성공/실패 알림을 받을 수 있어야 합니다.
  • 특히 실패했는데 아무도 모르면 며칠 동안 운영 데이터가 틀어질 수 있습니다.

➕ 15-1. 알림이 필요한 작업

  • 일별 통계 집계 실패
  • EP 파일 생성 실패
  • DB 백업 실패
  • Export 파일 정리 실패
  • 실패 알림 재처리 실패
  • Webhook 재처리 실패
  • 외부 API 연동 실패 급증
배치 실패
  ↓
Slack/이메일/관리자 알림 등록
  ↓
운영자 확인
  ↓
수동 재실행 또는 원인 수정

➕ 15-2. 알림 내용 예시

[배치 실패] DAILY_CONSULT_SUMMARY

대상 날짜: 2026-07-02
시작 시간: 2026-07-03 00:10
실패 시간: 2026-07-03 00:11
에러: DB connection timeout
처리 건수: 0
  • 알림에는 원인 파악에 필요한 최소 정보를 넣어야 합니다.
  • 민감정보는 알림 메시지에 포함하지 않는 것이 좋습니다.

✅ 16. 배치 작업 수동 실행 기능

  • 운영하다 보면 특정 배치를 다시 실행해야 할 때가 있습니다.
  • 관리자 페이지나 CLI 명령어로 수동 실행할 수 있게 만들면 편리합니다.

➕ 16-1. 수동 실행이 필요한 상황

  • 어제 통계 집계 실패
  • 특정 날짜 EP 파일 재생성
  • 실패 알림 재처리
  • Webhook 실패 이벤트 재처리
  • Export 정리 작업 재실행
  • 잘못된 집계 데이터 재계산

➕ 16-2. 수동 실행 시 주의점

  1. 실행 권한을 제한한다.
  2. 대상 날짜나 조건을 명확히 받는다.
  3. 중복 실행 방지를 적용한다.
  4. 실행 이력을 남긴다.
  5. 멱등하게 처리한다.
  6. 실행 전 예상 영향 범위를 보여준다.
관리자가 1년치 통계를 재집계
  ↓
DB 부하 급증 가능

대응:
날짜 범위 제한
Queue 분리
권한 제한
실행 전 확인

✅ 17. 배치 작업 배포 시 주의점

  • 배치 작업은 배포와도 충돌할 수 있습니다.
  • 배포 중 배치가 실행되면 코드 버전, DB 마이그레이션, 환경변수 문제로 실패할 수 있습니다.

➕ 17-1. 주의해야 할 상황

  • DB 마이그레이션 중 배치 실행
  • 배치 작업 코드가 배포 중간에 변경됨
  • Worker가 재시작되며 작업이 중단됨
  • 환경변수 누락으로 배치 실패
  • 여러 서버에서 스케줄러가 동시에 실행됨

➕ 17-2. 대응 방법

  1. 배치 실행 시간이 배포 시간과 겹치지 않게 한다.
  2. 배치 전용 Worker 또는 Scheduler를 분리한다.
  3. 중복 실행 Lock을 적용한다.
  4. 배포 후 배치 로그를 확인한다.
  5. DB 스키마 변경이 배치 코드와 호환되는지 확인한다.

✅ 18. 배치 작업 모듈 구조

  • 배치 작업은 Service 코드 여기저기에 흩어놓지 말고 모듈별로 정리하는 것이 좋습니다.

➕ 18-1. 폴더 구조 예시

src/
  batch/
    batch.module.ts
    batch-log.service.ts

    daily-stats/
      daily-stats.scheduler.ts
      daily-stats.service.ts

    ep-generator/
      ep-generator.scheduler.ts
      ep-generator.service.ts

    export-cleanup/
      export-cleanup.scheduler.ts
      export-cleanup.service.ts

    notification-retry/
      notification-retry.scheduler.ts
      notification-retry.service.ts

➕ 18-2. 구조 기준

  • Scheduler는 실행 시점만 담당합니다.
  • Service는 실제 비즈니스 로직을 담당합니다.
  • LogService는 실행 이력을 공통으로 저장합니다.
  • 무거운 처리는 Queue Worker로 넘길 수 있습니다.
Scheduler:
언제 실행할지 결정

Service:
무엇을 처리할지 결정

Queue Worker:
실제 무거운 작업 처리

LogService:
성공/실패 이력 저장

✅ 19. 실무 체크리스트

➕ 19-1. 배치 설계 체크리스트

  1. 이 작업이 실시간 API에서 처리될 필요가 없는가?
  2. 정해진 시간이나 주기에 실행하면 되는가?
  3. 실행 타임존이 명확한가?
  4. 작업 대상 날짜 범위가 정확한가?
  5. 중복 실행 방지가 필요한가?
  6. 같은 작업을 다시 실행해도 안전한가?
  7. 실행 이력을 남기는가?
  8. 실패 시 알림을 받을 수 있는가?

➕ 19-2. 운영 체크리스트

  1. 배치 작업별 실행 시간이 문서화되어 있는가?
  2. 배치 실패 로그를 확인할 수 있는가?
  3. 성공/실패 건수가 기록되는가?
  4. 배치가 너무 오래 걸릴 때 감지할 수 있는가?
  5. 여러 서버에서 중복 실행되지 않는가?
  6. 배포 시간과 배치 시간이 겹치지 않는가?
  7. 수동 재실행 방법이 있는가?
  8. 민감정보가 배치 로그나 알림에 노출되지 않는가?

➕ 19-3. 데이터 정합성 체크리스트

  1. 통계 집계 결과가 중복 저장되지 않는가?
  2. upsert 또는 unique 제약을 사용하는가?
  3. 실패 후 재실행해도 결과가 꼬이지 않는가?
  4. S3 삭제와 DB 상태 변경이 어긋날 경우 대응이 있는가?
  5. EP 파일 생성 실패 시 기존 정상 파일을 유지하는가?
  6. 재처리 작업이 같은 알림을 중복 발송하지 않는가?

✅ 20. AI를 활용해 배치 작업을 설계할 때 질문법

  • 배치 작업은 실행 시간, 대상 범위, 중복 실행, 실패 처리, 재실행 가능 여부를 함께 설명해야 합니다.
  • “Cron 만들어줘”라고만 하면 운영에서 필요한 안전장치가 빠질 수 있습니다.

➕ 20-1. 좋은 질문 예시

NestJS + Prisma 서비스에서 정기 배치 작업을 설계하고 싶어.

상황:
1. 매일 새벽 00:10에 전날 상담 신청 통계를 집계해야 함
2. 기준 타임존은 Asia/Seoul
3. 유입경로와 상품별로 total, pending, done, cancelled 수를 저장하고 싶음
4. 같은 날짜 배치를 수동으로 다시 실행할 수 있어야 함
5. 중복 실행은 막아야 함
6. 집계 결과는 upsert로 저장하고 싶음
7. 배치 실행 성공/실패 이력을 남기고 싶음
8. 실패하면 Slack 또는 관리자 알림으로 알려주고 싶음
9. 나중에 EP 파일 생성, Export 파일 정리 배치도 같은 구조로 추가하고 싶음

요청:
- Prisma 모델 설계
- Cron 설정
- 타임존 처리
- 중복 실행 방지
- 멱등성 처리
- BatchJobLog 구조
- 실패 알림 구조
- 폴더 구조
를 실무 기준으로 설명해줘.

➕ 20-2. AI 답변 검증 기준

  1. 타임존을 명확히 처리하는가?
  2. 배치 대상 날짜 범위를 정확히 계산하는가?
  3. 중복 실행 방지 방식을 설명하는가?
  4. 같은 작업 재실행 시 upsert 등 멱등성을 고려하는가?
  5. 실행 이력 테이블을 제안하는가?
  6. 실패 시 알림을 고려하는가?
  7. Cron이 무거운 작업을 직접 처리하지 않고 Queue 분리를 고려하는가?
  8. 배포와 배치 실행 충돌 가능성을 언급하는가?

📌 요약

  • 배치 작업은 사용자의 실시간 요청과 별개로 정해진 시간이나 주기에 자동 실행되는 작업입니다.
  • 통계 집계, 실패 작업 재처리, EP 파일 생성, 오래된 Export 파일 정리, 백업, 상태 자동 변경 같은 작업이 배치에 적합합니다.
  • NestJS에서는 @nestjs/schedule을 사용해 Cron 기반 스케줄러를 구성할 수 있습니다.
  • 한국 서비스라면 Asia/Seoul 기준 타임존을 명확히 지정하고, 집계 날짜 범위를 정확히 계산해야 합니다.
  • 배치 작업은 중복 실행될 수 있으므로 DB 상태 기록, Redis Lock, Queue Job ID, upsert 같은 방식으로 중복과 멱등성을 관리해야 합니다.
  • 배치 실행 결과는 BatchJobLog 같은 테이블에 기록해 성공/실패, 처리 건수, 실행 시간을 추적해야 합니다.
  • 무거운 작업은 Cron이 직접 처리하기보다 Queue에 등록하고 Worker가 처리하는 구조가 안정적입니다.
  • 배치 실패는 조용히 지나가면 안 되며, 운영자가 확인할 수 있도록 알림과 재실행 방법을 준비해야 합니다.

0개의 댓글