[Spring] Batch와 Scheduler
- -
Scheduler (스케쥴러)
1) Scheduler의 개념과 목적
● 개념
정해진 시간에 작업을 실행하거나 주기적으로 반복 작업을 수행하는 역할
● 목적
일정한 시간에 특정 작업을 실행하여 비즈니스 프로세스를 자동화
효율적인 작업 스케줄링과 시간 관리를 가능하게 하는 것
2) Scheduler의 구성요소
● 작업 (Job)
실행할 작업의 단위로, 스케줄링된 시간에 실행되는 코드 또는 프로세스
● 트리거 (Trigger)
작업이 실행될 시간을 정의하는 요소 (일정 시간, 주기 또는 특정 조건 등)
● 스케쥴러 (Scheduler)
스케줄링 작업을 관리하고 실행하는 주체입니다.
트리거된 작업을 실행하며, 작업의 예약, 중지, 수정 등을 관리합니다.
3) 주요 Scheduler
① Spring Scheduler
Spring Scheduler는 스프링 프레임워크에서 제공하는 스케줄링 기능.
주로 어플리케이션 내에서 간단한 작업 스케줄링이 필요한 경우에 사용됩니다.
@Scheduled 어노테이션을 사용하여 메서드를 스케줄링할 수 있습니다 → 간단함
@Configuration
@EnableScheduling
//스프링 애플리케이션에서 스케줄링 활성화
public class SchedulerConfig {
@Scheduled(cron = "0 0 8 * * ?") // 매일 오전 8시에 실행 (크론 표현식)
public void scheduleBatchJob() {
// 메소드 호출
batchJobLauncher.runBatchJob();
}
}
② Quartz Scheduler
자바 기반의 오픈 소스 스케줄링 라이브러리
대규모 작업 스케줄링 및 클러스터링 지원, 스케쥴 작업 실패 시 후처리 기능이 있습니다.
Quartz 예시 - 아침 9시마다 출석체크하는 스케쥴
● 1. 사용하기 전 종속성 추가
<!-- Quartz Scheduler -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
● 2. 클래스 생성하여 JobDetail, Scheduller, Trigger 생성
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@Configuration
public class SchedulerConfig {
private final AttendanceCheckJob attendanceCheckJob;
@Autowired
public SchedulerConfig(AttendanceCheckJob attendanceCheckJob) {
this.attendanceCheckJob = attendanceCheckJob;
}
@Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
schedulerFactoryBean.setJobDetails(attendanceCheckJobDetail());
schedulerFactoryBean.setTriggers(attendanceCheckTrigger());
return schedulerFactoryBean;
}
@Bean
public JobDetail attendanceCheckJobDetail() {
return JobBuilder.newJob(attendanceCheckJob.getClass())
.withIdentity("attendanceCheckJob")
.storeDurably()
.build();
}
@Bean
public Trigger attendanceCheckTrigger() {
return TriggerBuilder.newTrigger()
.forJob(attendanceCheckJobDetail())
.withIdentity("attendanceCheckTrigger")
.withSchedule(CronScheduleBuilder.cronSchedule("0 0 9 * * ?")) // 매일 오전 9시에 실행
.build();
}
}
● 3. Job 인터페이스를 구현하여 출석체크 작업을 정의
(인터페이스 Job이 있다고 가정)
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.stereotype.Component;
@Component
public class AttendanceCheckJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
// 출석체크 작업 로직 작성
System.out.println("Attendance check is executed!");
}
}
4) Cron 표현식
● 구조
초 (Seconds) 분 (Minutes) 시 (Hours) 일 (Day) 월 (Month) 요일 (Day of week)
각 필드는 숫자나 특수 문자로 표현되며, 이를 조합하여 원하는 시간을 표현할 수 있습니다.
● 필드 표
설명 | 범위 | 허용되는 특수문자 | |
초 (Seconds) | 초 단위 시간을 나타냄 | 0-59 | , - * / |
분 (Minutes) | 분 단위 시간을 나타냄 | 0-59 | , - * / |
시 (Hours) | 시간을 나타냄 | 0-23 | , - * / |
일 (Day) | 월별 일자를 나타냄 | 1-31 | , - * ? / L W |
월 (Month) | 월을 나타냄 | 1-12 또는 JAN-DEC | , - * / |
요일 (Day of week) | 주별 요일을 나타냄 | 0-7 또는 SUN-SAT | , - * ? / L # |
● 특수문자 표
설명 | |
* (Asterisk) | 해당 필드의 모든 값을 나타냅니다. |
, (Comma) | 여러 값을 지정할 때 사용합니다. ','로 구분하여 값을 나열합니다. |
- (Hyphen) | 범위를 지정할 때 사용합니다. 시작 값과 끝 값 사이의 값을 포함합니다. |
/ (Slash) | 증분 값을 지정할 때 사용합니다. 시작 값부터 지정한 증분만큼 증가합니다. |
? (Question mark) | 일자 또는 요일에 대한 특정 값을 지정하지 않을 때 사용합니다. |
L (Last day) | 월별 일자에서 마지막 날을 의미합니다. |
W (Weekday) | 월별 일자에서 평일(주중)을 의미합니다. |
# (Number) | 주별 실행 중 몇 번째 요일을 지정할 때 사용합니다. '#' 뒤에 숫자를 지정합니다. |
● 예시 1
@Scheduled(cron = "0 30 10 * *")
// 매일 오전 10시 30분에 작업을 실행
● 예시 2
@Scheduled(cron = "0 0 12 * *")
// 매일 정오 (12시 0분 0초)에 작업을 실행
● 예시 3
@Scheduled(cron = "0 30 8 ? * MON-FRI")
// 평일(월요일부터 금요일까지) 오전 8시 30분에 작업을 실행
● 예시 4
@Scheduled(cron = "0 0/15 * * * ?")
// 매시 0분과 15분에 각각 작업을 실행
● 예시 5
@Scheduled(cron = "0 0 6,18 * * ?")
// 매일 아침 6시와 저녁 6시에 작업을 실행
● 예시 6
@Scheduled(cron = "0 0 0 1 1/3 ?")
// 매년 1월 1일부터 시작하여 3개월마다 1일 0시에 작업을 실행
Batch
1) Batch 처리 개념
배치 처리는 대용량 데이터를 일괄적으로 처리하는 작업을 의미
2) Batch 처리 방식
① Chunk 방식
Chunk : 큰 데이터를 작은 덩어리로 분할하는 것
즉, Chunk 처리 방식은 큰 데이터를 작게 분할하여 처리하는 방식을 말합니다.
ItemReader, ItemProcessor, ItemWriter 등을 사용
② Tasklet 방식
단일 작업 단위인 Tasklet을 순차적으로 실행하는 방식
Tasklet은 실제 작업을 수행하는 코드를 담고 있는 인터페이스 또는 클래스
Step에서 Tasklet을 정의하고, Tasklet 내부에서 작업을 처리합니다.
③ 비교
Tasklet 처리 방식 | Chunk 처리 방식 | |
처리 방식 | 반복적인 작업을 수행하는 하나의 Tasklet 클래스로 구현 | 큰 데이터를 작은 덩어리로 나누어서 처리하는 방식 |
데이터 처리량 | 대용량 데이터 처리에 적합 | 대용량 데이터 처리에 매우 적합 |
트랜잭션 범위 | 하나의 트랜잭션 안에서 전체 작업이 처리됨 | 각 Chunk 내에서 별도의 트랜잭션이 처리됨 |
에러 핸들링 | 재시작 기능이 없어서 실패 시 다시 시작하려면 전체 Job을 재시작해야 함 |
실패한 Chunk만 다시 시작 가능하여 효율적인 재시작이 가능함 |
병렬 처리 | 멀티스레드로 처리가 어려움 | 멀티스레드로 병렬 처리가 가능함 |
구현 복잡도 | 단순한 반복적인 작업에 적합 복잡한 로직 처리에 적합 |
Step, Chunk 구성 등 복잡한 설정이 필요함 |
3) Batch 처리 구조
● 실행순서
- Job Script에 배치 구성요소를 정의합니다.
- Job Runner로 Job Launcher를 호출하고 Job을 실행시킵니다.
- Job은 여러 개의 Step으로 구성됩니다.
- 각 Step은 ItemReader를 사용하여 데이터를 읽어옵니다.
- 읽어온 데이터는 ItemProcessor(Business Logic)를 통해 가공/처리됩니다.
- 가공/처리된 데이터는 ItemWriter를 통해 저장하거나 출력됩니다.
- ExecutionContext를 사용하여 Step 또는 Job 간의 데이터 공유가 이루어집니다.
- 각 Step이 성공적으로 완료되면 다음 Step으로 진행되거나 Job이 종료됩니다
* JobRepository는 배치 처리의 실행 상태 및 메타데이터를 관리합니다.
● 구성요소
- Job Script : 배치 작업을 정의하는 스크립트 또는 설정 파일 (주로 XML, YAML, 또는 Java Config와 같은 형식)
배치 작업의 구성 요소인 Step, ItemReader, ItemProcessor, ItemWriter 등이 정의되어 있습니다. - Job Runner : Job Launcher를 호출하여 Job을 시작하고, Job 실행 상태를 관리합니다.
- Job Launcher : 배치 작업을 실행하는 인터페이스를 제공하는 클래스.
Job을 시작하고, Job 실행 상태를 관리하며, Job 실행에 필요한 Job Parameter를 설정합니다.
Spring Batch에서는 SimpleJobLauncher가 기본 Job Launcher로 제공됩니다. - Job : 하나의 배치 작업으로 여러 Step으로 구성됩니다. 배치 처리에 필요한 모든 정보가 담겨져있습니다.
- Job Instance : Job이 실행될 때 생성되는 하나의 독립적인 실행 인스턴스.
같은 Job을 여러 번 실행할 때마다 새로운 Job Instance가 생성됩니다. - Job Execution : Job이 실제로 실행되는 것
Job Execution은 성공적으로 완료되거나 실패할 수 있습니다. - Job Repository : Job의 실행 상태, Step의 실행 상태 등의 정보를 관리합니다.
- Step : 하나의 배치 작업 단위 ( 즉, Job 내에서 실행되는 개별적인 작업 단위 )
ItemReader, ItemProcessor, ItemWriter, Tasklet 등의 구성 요소들을 가지고 있습니다. - ItemReader : 배치 처리에서 데이터를 읽는 역할을 수행합니다.
- ItemWriter : ItemProcessor에서 가공/처리된 데이터를 저장하거나 출력
- ItemProcessor : 배치 처리에서 주로 Business Logic을 담당하는 역할
데이터를 처리/가공하는 역할을 합니다.
ItemReader와 ItemWriter 사이에 위치하며, ItemReader로부터 읽어온 데이터를 가공하여 ItemWriter로 전달합니다.
4) Scheduler와 Batch의 연계
① 연계
스케줄러를 사용하여 배치 작업을 스케줄링하고 실행할 수 있습니다.
스케줄러는 일정한 시간 또는 주기에 따라 작업을 트리거하고, 배치 작업은 해당 트리거에 의해 실행됩니다.
② 연계했을 때 장점
● 대용량 데이터 처리
대량의 데이터를 작은 청크로 나누어 처리하므로 메모리 사용량을 최적화하고, 시스템의 부하를 분산시킬 수 있습니다.
배치 작업은 백그라운드에서 비동기적으로 처리되므로 실시간 작업과는 달리 대용량 데이터 처리에 최적화되어 있습니다.
● 작업의 안전성과 신뢰성
배치 작업은 장애 처리 및 롤백 기능을 제공하여 안정적인 처리를 보장합니다.
실패한 작업을 다시 실행하거나 이전 상태로 롤백할 수 있어 작업의 안정성과 신뢰성을 강화할 수 있습니다.
● 자동화된 작업 관리
스케줄러를 사용하여 배치 작업을 스케줄링하면 반복적이고 일정한 작업을 자동화할 수 있습니다.
작업을 사람이 수동으로 실행할 필요가 없으며, 정해진 시간에 자동으로 실행되므로 운영 부담을 줄일 수 있습니다.
∴ 결론적으로 시간과 자원을 절약하고, 데이터 처리의 효율성을 높일 수 있습니다.
③ 배치작업 스케쥴링의 예시
● 은행
은행은 매일 밤에 거래 데이터를 처리하고 정산 작업을 실행하는데 스케줄러를 사용합니다.
이를 통해 거래 데이터의 일관성과 정확성을 유지하고, 정산 과정을 자동화하여 인력과 시간을 절약합니다.
● 항공사
항공사는 항공 예약 시스템과 결제 시스템을 일정 주기로 동기화하는 배치 작업을 스케줄링합니다.
스케줄러를 사용하여 항공편 정보와 결제 내역을 일치시키고, 예약 시스템의 데이터 정합성을 유지합니다.
● 전자상거래 플랫폼
일 새로운 주문 데이터를 처리하고 배송 준비 작업을 실행하는 배치 작업을 스케줄링합니다.
스케줄러를 사용하여 주문 처리 및 배송 상태 업데이트를 자동화하여 고객에게 정확한 주문 정보를 제공합니다.
● 제조업
생산 계획과 재고 관리를 위한 작업을 스케줄링합니다.
스케줄러를 사용하여 원자재 구매, 생산 라인 가동, 제품 출하 등의 작업을 정확한 타이밍에 자동으로 실행합니다.
2023.06.30 - [Spring] - Spring MVC 구조
'Spring' 카테고리의 다른 글
[Spring] Spring Security (Part.1) - 개념, 인증(Authentication), 권한 부여(Authorization)에 대한 설명 및 작동순서 (0) | 2023.07.25 |
---|---|
[Spring] Spring Scheduler 이용하여 Slack 자동 알림 구현하기 (Slack 연동) (0) | 2023.07.20 |
[Spring] Pageable과 PageRequest 개념과 비교 (0) | 2023.07.19 |
[Spring] Spring MVC 구조 (0) | 2023.06.30 |
[Spring] 스프링 컨테이너(Spring Container) & 빈(Bean) (11) | 2023.06.29 |
소중한 공감 감사합니다