Spring Boot, 작업 스케쥴러 데몬 구현하기

먼저 읽어볼만한 글

build.gradle

작업 스케쥴러 성격의 Spring Boot 프로젝트를 새로 생성할 경우 /build.gradle 파일을 아래 내용으로 교체한다. 기존 프로젝트에 적용하고자 할 경우에는 이 부분은 생략한다.

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath group: 'org.springframework.boot', name: 'spring-boot-gradle-plugin', version: '1.5.6.RELEASE'
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'

jar {
    baseName = 'spring-boot-task-scheduler-example'
    version = '0.0.1'
}

repositories {
    mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    compile group: 'org.springframework.boot', name: 'spring-boot-starter'
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.5'
}
  • Spring Boot 기반의 웹 애플리케이션 개발시에는 spring-boot-starter-web 스타터를 프로젝트에 추가했지만 작업 스케쥴러 성격의 애플리케이션에서는 웹 애플리케이션의 기능이 필요 없으므로 Spring Boot의 기본 기능만 제공하는 spring-boot-starter 스타터를 추가한다.(빌드시 약 5.8MB로 매우 가볍다.)

  • spring-boot-starter 스타터는 spring-boot-starter-logging(Logback 사용) 스타터를 기본 포함한다. 작업 성격에 따라 spring-boot-starter-jdbc, spring-boot-starter-mail, spring-boot-starter-redis 스타터를 추가하면 된다.

Application.java

/src/main/java/com.jsonobject.example/Application.java 파일을 아래와 같이 작성한다.

package com.jsonobject.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class Application {

    public static void main(String[] args) {

        ApplicationContext ctx = SpringApplication.run(Application.class, args);
    }

    @Bean
    public TaskScheduler taskScheduler() {

        return new ConcurrentTaskScheduler();
    }

    @Bean
    public TaskScheduler taskScheduler() {

        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(10);

        return taskScheduler;
    }
}
  • @EnableScheduling을 명시하여 작업 스케쥴러를 활성화한다. 명시하지 않을 경우 애플리케이션은 시작과 동시에 종료된다. 애플리케이션은 대기 상태를 유지하며 정해진 일정대로 ScheduledThreadPoolExecutor에 의해 관리되는 Worker 쓰레드를 실행하여 스케쥴 작업을 처리한다.

  • 작업 스케쥴러를 구현하려면 해당 스케쥴을 관리할 org.springframework.scheduling.TaskScheduler 빈이 등록되어 있어야 한다. 쓰레드 풀이 필요하다면 ThreadPoolTaskScheduler 빈을 등록하고 단일 쓰레드로 충분하다면 ConcurrentTaskScheduler 빈을 등록한다.

  • 단일 쓰레드로 관리될 경우, 2개 이상의 작업을 같은 시간에 실행되도록 설정시 1개 작업을 먼저 실행하여 완료 후 다른 작업을 순차적으로 실행한다. 여러 작업이 동시에 실행되기를 원할 경우 쓰레드 풀의 크기를 2개 이상으로 설정하면 된다. 쓰레드 풀을 구성하지 않을 경우 작업 스케쥴의 의해 실행될 빈의 메써드에 @Async를 명시하는 것도 한 방법이다.

CronTable.java

/src/main/java/com.jsonobject.example/CronTable.java 파일을 아래와 같이 작성한다.

package com.jsonobject.example;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class CronTable {

    // 매일 5시 30분 0초에 실행한다.
    @Scheduled(cron = "0 30 5 * * *")
    public void aJob() {

        // 실행될 로직
    }

    // 매월 1일 0시 0분 0초에 실행한다.
    @Scheduled(cron = "0 0 0 1 * *")
    public void anotherJob() {

        // 실행될 로직
    }

    // 애플리케이션 시작 후 60초 후에 첫 실행, 그 후 매 60초마다 주기적으로 실행한다.
    @Scheduled(initialDelay = 60000, fixedDelay = 60000)
    public void otherJob() {

        // 실행될 로직
    }
}
  • 특정 주기로 실행될 메써드 레벨에 @Scheduled를 명시한다. 위 예와 같이 cron 문법을 사용하여 편리하게 작업 실행 시점을 결정할 수 있다.
  • @Scheduled이 명시된 메써드는 아규먼트를 가질 수 없다. 또한 반환 타입은 void이어야 한다.

참고 글

저작자 표시 비영리 동일 조건 변경 허락
신고