Spring Batch 개요
✅Spring FrameWork + Batch(일괄 처리)
대용량 일괄처리의 편의를 위해 설계된 가볍고 포괄적인 배치 프레임 워크
언제 사용할까?
- 대용량 비즈니스 데이터를 복잡한 작업으로 처리
- 특정한 시점에 스케쥴러를 통해 자동 작업
이와 같이, 대용량의 특정 작업을 특정 시간에 Batch를 통해 최적화 하여 처리할 수 있다.
Batch 장점
✅ 사용자가 적을 때 동작하게 설정하여 컴퓨터 자원 효율적 사용
✅ 특정한 시점에 특정한 행동을 자동화
Batch 주의점
❗ 대용량 데이터를 직접 사용하여 데이터 무결성(유효성 검사) 필수
❗ 잦은 I/O → 네트워크 비용 증가 : 데이터 조회 후 캐싱하여 해결 ✅
❗ Batch 시스템이 돌아갈 때, 다른 시스템에 영향이 미치는지 확인
❗ Batch ≠ 스케쥴러, 즉 스케쥴링 Framework 사용
➕ Batch는 지정된 작업을 일괄 적으로 처리하는 것, Scheduler는 특정한 시간이 작동 하도록 함
Scheduler Framework
- Spring Scheduler
- Quartz
두 프레임워크 간단한 차이점
- Spring Scheduler
Spring Scheduler 같은 경우, SpringBoot Starter에 기본적으로 포함되어 있어, 별도로 의존성을 추가하여 사용하지 않아도 된다는 장점이 있다. 또한 사용이 쉽고 기본적으로 단일 스레드 형식 → 간단한 로직에 간단히 사용 👍
- Quartz
Quartz 같은 경우, 스케쥴러 간의 Clustering (군집, 같은 종류의 묶음) 제공하며 In-memory Job Scheduler도 제공한다고 한다. → Spring Scheduler에 비해 어렵긴 하지만, 많은 종류의 메서드 제공
간단하게 스케쥴러 사용해보기
Spring Scheduler
- main method에 @EnableScheduling 추가
@EnableScheduling
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@Component
public class Scheduler {
@Scheduled(fixedDelay = 1000)
public void schedulerFixedDelay (){
System.out.println("Display for 1s -> " + new Date());
// 1초마다 현재 시간 찍어보기
}
}
. ____ _ __ _ _
/\\\\ / ___'_ __ _ _(_)_ __ __ _ \\ \\ \\ \\
( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\
\\\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.7.2)
2022-08-10 13:19:34.362 INFO 11352 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication using Java 11.0.15.1 on DESKTOP-B841SQJ with PID 11352 (C:\\Users\\kangheon\\Desktop\\회사\\demo\\build\\classes\\java\\main started by kangheon in C:\\Users\\kangheon\\Desktop\\회사\\demo)
2022-08-10 13:19:34.364 INFO 11352 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to 1 default profile: "default"
2022-08-10 13:19:34.679 INFO 11352 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 0.514 seconds (JVM running for 0.991)
Display for 1s -> Wed Aug 10 13:19:34 KST 2022
Display for 1s -> Wed Aug 10 13:19:35 KST 2022
Display for 1s -> Wed Aug 10 13:19:36 KST 2022
Display for 1s -> Wed Aug 10 13:19:37 KST 2022
Quartz
동작 과정
- 의존성 추가
//quartz-scheduler 의존성 추가
implementation group: 'org.quartz-scheduler', name: 'quartz', version: '2.3.2'
- application.yml을 통한 Quartz 설정
spring:
quartz:
wait-for-jobs-to-complete-on-shutdown: true#종료 시 실행 중인 작업이 완료 때까지 대기
properties:
org:
quartz:
scheduler:
skipUpdateCheck: true
threadPool:#스레드 관련
class: org.quartz.simpl.SimpleThreadPool
threadCount: 5
jobStore:
class: org.quartz.simpl.RAMJobStore#인메모리 방식
plugin:
shutdownhook:#로깅 시스템이 초기화 되면 종료 후크 등록
# war배포시 자동 비활성화
class: org.quartz.plugins.management.ShutdownHookPlugin
cleanShutdown: true\\
- Job class 생성
package com.example.demo.quartz.job;
import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.quartz.QuartzJobBean;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
public class CronJob extends QuartzJobBean {
private int MAX_SLEEP_IN_SECONDS = 5;
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
/*
* executeInternal 설명
* 작업에 필요한 JobDataMap은 이미 scheduleJobDetail 부분에서 생성 되어있고,
* JobExecutionContext 안에는 Trigger, JobDetail(작업해야될 객체) 등등
* 스케쥴링에 필요한 모든것이 담겨있습니다.
* */
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
String Dev = jobDataMap.getString("Dev");
String Company = jobDataMap.getString("Company");
JobKey jobKey = context.getJobDetail().getKey();
System.out.println("============================================");
System.out.printf("Test By %s from %s %n", Dev, Company);
System.out.printf("CronJob started :: jobKey : %s %n", jobKey);
System.out.println("Quartz 실행 중입니다. Date : " + new Date());
System.out.printf("CronJob ended :: jobkey : %s %n", jobKey);
System.out.println("============================================");
}
}
- → job이란? Trigger가 실행 되었을 때, 작동되는 코드 (비즈니스 로직)
- 작업에 필요한 Trigger 및 작업 해야 될 객체 생성
package com.example.demo;
import com.example.demo.quartz.job.CronJob;
import org.quartz.*;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public JobDetail scheduleJobDetail() {
JobDataMap jobDataMap = new JobDataMap();
jobDataMap.put("Dev", "최강헌");
jobDataMap.put("Company", "공부용");
return JobBuilder.newJob(CronJob.class)
.withIdentity("testSchedule")
.usingJobData(jobDataMap)
.storeDurably()
.build();
}
@Bean
public Trigger scheduleJobTrigger() {
//cron
CronScheduleBuilder cronBuilder =
CronScheduleBuilder.cronSchedule("0/20 * * * * ?");
return TriggerBuilder // Builder 패턴
.newTrigger() // 새로운 트리거를 만들고
.forJob(scheduleJobDetail()) // JobDetail -> 작업을 해야되는 객체
.withIdentity("scheduleTrigger") // Trigger key
.withSchedule(cronBuilder) // cron 표현식 : 해당 내용은 참조 문헌에 정리
.build();
}
}
- 실행결과
============================================
Test By 최강헌 from 공부용
CronJob started :: jobKey : DEFAULT.testSchedule
Quartz 실행 중입니다. Date : Wed Aug 10 16:14:20 KST 2022
CronJob ended :: jobkey : DEFAULT.testSchedule
============================================
============================================
Test By 최강헌 from 공부용
CronJob started :: jobKey : DEFAULT.testSchedule
Quartz 실행 중입니다. Date : Wed Aug 10 16:14:40 KST 2022
CronJob ended :: jobkey : DEFAULT.testSchedule
============================================
============================================
Test By 최강헌 from 공부용
CronJob started :: jobKey : DEFAULT.testSchedule
Quartz 실행 중입니다. Date : Wed Aug 10 16:15:00 KST 2022
CronJob ended :: jobkey : DEFAULT.testSchedule
============================================
2022-08-10 16:15:02.165 INFO 17816 --- [quartzScheduler] o.q.p.management.ShutdownHookPlugin : Shutting down Quartz...
2022-08-10 16:15:02.165 INFO 17816 --- [quartzScheduler] org.quartz.core.QuartzScheduler : Scheduler quartzScheduler_$_NON_CLUSTERED shutting down.
2022-08-10 16:15:02.165 INFO 17816 --- [quartzScheduler] org.quartz.core.QuartzScheduler : Scheduler quartzScheduler_$_NON_CLUSTERED paused.
2022-08-10 16:15:02.165 INFO 17816 --- [quartzScheduler] org.quartz.core.QuartzScheduler : Scheduler quartzScheduler_$_NON_CLUSTERED shutdown complete.
2022-08-10 16:15:02.167 INFO 17816 --- [ionShutdownHook] o.s.s.quartz.SchedulerFactoryBean : Shutting down Quartz Scheduler
Process finished with exit code 130
참고자료
장,단점 : https://velog.io/@kihwanyu/Spring-Batch-정리
스케줄링 : https://sabarada.tistory.com/113
Quartz 실습 : https://gupuroom.tistory.com/m/2
cron 표현식 : https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=rhkrehduq&logNo=221426709905
'language > Spring' 카테고리의 다른 글
[Spring] @Transactional 전파와 격리 (0) | 2022.07.05 |
---|---|
[JPA] Native Query to DTO 맵핑 (0) | 2022.05.15 |
[Spring Security] Spring Security 이란? (0) | 2022.05.01 |
[Spring] Spring MVC 패턴 & Model2 방식 (0) | 2022.05.01 |