본문 바로가기
TypeScript

[NestJS] Task Scheduling

by yonikim 2025. 4. 7.
728x90

 

서비스를 개발하다 보면 주기적으로 동일한 작업을 처리해야 하는 경우가 생긴다. 

Task Scheduling 은 특정 시간 간격으로 반복되거나, 특정 시간에 실행되도록 예약된 작업을 자동으로 수행하는 기법이다. 이를 통해 서버에서 반복적인 작업을 자동화하고, 백그라운드에서 실행할 수 있다.

 

1. Cron Jobs (리눅스)

운영체제에서 제공하는 `cron` 스케줄러를 활용할 수 있다.

# 1. crontab 편집
$ crontab -e

# 2. cron 추가
# 매일 자정에 실행
0 0 * * * /usr/bin/node /home/user/scripts/backup.js

# 3. cron 실행
$ service cron start

 

※ Cron 표현식 구조

*    *    *    *    *    *
┬    ┬    ┬    ┬    ┬    ┬
│    │    │    │    │    │
│    │    │    │    │    └─ 초 (0 - 59)
│    │    │    │    └───── 분 (0 - 59)
│    │    │    └───────── 시간 (0 - 23)
│    │    └───────────── 일 (1 - 31)
│    └────────────────── 월 (1 - 12)
└────────────────────── 요일 (0 - 7, 07은 일요일)

 

2. ⭐️ 백엔드 프레임워크 

NestJS 의 `@nestjs/schedule` 모듈을 활용하면 크론 작업을 쉽게 설정할 수 있다.

 

1. `@nestjs/schedule` 설치 

$ npm install @nestjs/schedule

 

2. `ScheduleModule` 설정

import { Module } from '@nestjs/common';
import { ScheduleModule } from '@nestjs/schedule';
import { TasksService } from './tasks.service';

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

 

3. Task Scheduling 사용하기 

1) 특정 시간에 실행(`@Cron()`)

import { Injectable, Logger } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  // 매일 자정(00:00)에 실행
  @Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT)
  handleCron() {
    this.logger.log('매일 자정에 실행되는 작업');
  }

  // 매 5초마다 실행
  @Cron('*/5 * * * * *')
  handleFiveSecondCron() {
    this.logger.log('매 5초마다 실행되는 작업');
  }
}

 

2) 일정 간격으로 실행(`@Interval()`)

import { Injectable, Logger } from '@nestjs/common';
import { Interval } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  @Interval(10000) // 10초마다 실행
  handleInterval() {
    this.logger.log('10초마다 실행되는 작업');
  }
}

 

3) 특정 시간 후 한 번 실행(`@Timeout()`)

import { Injectable, Logger } from '@nestjs/common';
import { Timeout } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  @Timeout(5000) // 앱 실행 후 5초 후 실행
  handleTimeout() {
    this.logger.log('앱 시작 후 5초 뒤에 실행되는 작업');
  }
}

 

 

4. 동적으로 Task Scheduling 제어하기

`SchedulerRegistry` 를 사용하면 런타임에 동적으로 스케줄을 추가하거나 제거할 수 있다. 

import { Injectable, Logger } from '@nestjs/common';
import { CronJob } from 'cron';
import { SchedulerRegistry } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  constructor(private schedulerRegistry: SchedulerRegistry) {}

  addCronJob(name: string, time: string) {
    const job = new CronJob(time, () => {
      this.logger.log(`동적 크론 작업 실행됨: ${name}`);
    });

    this.schedulerRegistry.addCronJob(name, job);
    job.start();
  }

  deleteCronJob(name: string) {
    this.schedulerRegistry.deleteCronJob(name);
    this.logger.log(`크론 작업 삭제됨: ${name}`);
  }
}

 

 

[References]

https://docs.nestjs.com/techniques/task-scheduling

728x90