기술과 산업/언어 및 프레임워크

Spring Boot 시리즈 31편 – Spring Scheduler: 정기 작업 자동화 및 서비스 운영 효율화 전략

B컷개발자 2025. 5. 19. 16:20
728x90

Spring Boot에서 Scheduler를 활용한 정기 작업 자동화 방법을 설명합니다. 단순 스케줄링부터 병렬 실행, 조건 기반 트리거, 운영 환경에서의 안정적 실행 전략까지 정리했습니다.

 

정기적으로 실행되어야 하는 백그라운드 작업은 어떤 서비스든 반드시 존재합니다.
예를 들어, 다음과 같은 시나리오입니다.

  • 매일 오전 3시에 정산 데이터를 집계
  • 5분마다 API 연동 데이터를 동기화
  • 매시 정각에 캐시를 갱신하거나 DB 정리 작업 실행

Spring Boot는 @Scheduled 어노테이션 기반으로 간단하면서도 강력한 정기 작업 실행 기능을 제공합니다.
이번 글에서는 스케줄링 기본 개념부터, 운영환경에서 주의해야 할 병렬 실행 문제, 예외 대응까지 실전 예시로 정리합니다.


1. 스케줄링 기본 설정

Spring Boot는 기본적으로 Spring Framework의 @Scheduled를 사용할 수 있도록 지원합니다.
단, 이를 활성화하려면 @EnableScheduling 어노테이션을 명시해야 합니다.

@SpringBootApplication
@EnableScheduling
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

2. @Scheduled 사용법

기본적인 @Scheduled 사용 방법은 다음과 같습니다.

@Component
public class DataSyncScheduler {

    @Scheduled(fixedRate = 300000) // 5분마다 실행
    public void syncExternalData() {
        System.out.println("외부 데이터 동기화 실행: " + LocalDateTime.now());
    }
}

속성 설명

fixedRate 이전 실행 종료 여부와 상관없이 지정된 간격마다 실행
fixedDelay 이전 작업이 끝난 후 지정된 간격 뒤에 실행
cron Cron 표현식으로 유연한 시간 설정 가능

예시: cron 표현식

@Scheduled(cron = "0 0 3 * * *") // 매일 새벽 3시
public void generateDailyReport() {
    // 리포트 생성 로직
}

표현식 예시 설명

0 0 * * * * 매시 정각
0 */10 * * * * 10분마다
0 0 0 * * MON 매주 월요일 자정

3. 병렬 실행 방지 전략

기본적으로 @Scheduled 메서드는 단일 쓰레드에서 실행되므로 병렬 실행이 발생하지 않지만,
다음과 같은 상황에서는 별도 설정이 필요합니다.

  • 실행 시간이 오래 걸리는 작업이 다시 호출되는 경우
  • 클러스터 환경에서 동일한 Job이 여러 서버에서 중복 실행되는 경우

1) 싱글 쓰레드 TaskExecutor 설정

@Configuration
public class SchedulerConfig {

    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(1); // 단일 쓰레드
        scheduler.setThreadNamePrefix("scheduler-");
        return scheduler;
    }
}

2) 클러스터 중복 실행 방지

운영 환경에서는 **스케줄 락(Lock)**을 활용하는 것이 일반적입니다.
대표적인 라이브러리: ShedLock

implementation 'net.javacrumbs.shedlock:shedlock-spring:4.40.0'
implementation 'net.javacrumbs.shedlock:shedlock-provider-jdbc-template:4.40.0'
@SchedulerLock(name = "generateReportJob", lockAtLeastFor = "PT10M", lockAtMostFor = "PT30M")
@Scheduled(cron = "0 0 3 * * *")
public void generateReportJob() {
    // 클러스터 중복 실행 방지됨
}

4. 예외 처리 및 장애 방지

스케줄링 로직에 예외가 발생하면, 다음 실행 시에도 영향이 갈 수 있습니다.
예외 처리를 철저히 해야 스케줄러가 중단되지 않습니다.

@Scheduled(cron = "0 0 * * * *")
public void safeTask() {
    try {
        // 작업 수행
    } catch (Exception e) {
        log.error("스케줄 작업 실패", e);
    }
}

또한, 모든 스케줄 작업은 단위 책임만 부여하고,
로그를 반드시 남기며,
장애 시 알림(Slack, 메일) 연동도 고려해야 합니다.


5. 스케줄러 운영 관리 팁

항목 전략

로깅 작업 시작/종료 시각, 결과 상태, 처리 건수 반드시 로그 기록
가시화 Prometheus, Grafana 등으로 Job 성공/실패 시각 시각화
상태 관리 DB에 작업 실행 이력 저장 (수행 여부 모니터링용)
테스트 스케줄러도 CommandLineRunner 또는 수동 트리거로 테스트 가능하게 설계
운영 정책 Job Timeout 설정, Lock 전략 적용, 장애 시 리트라이 여부 판단

마무리 요약

항목 요약

기본 구조 @EnableScheduling + @Scheduled 기반 간편 구현 가능
실행 방식 fixedRate, fixedDelay, cron 등 다양한 주기 설정
병렬 제어 단일 쓰레드 또는 ShedLock 활용
예외 대응 try-catch와 알림 연동 필수
운영 전략 로깅, 모니터링, 실행 이력 저장 등 관리 체계화 필요

다음 편 예고

Spring Boot 시리즈 32편: OpenFeign을 활용한 외부 API 연동 아키텍처 설계

728x90