오늘은 Spring Boot에서 Linux에서 clontab을 구동하는 것처럼 해당 method를 일정주기로 혹은 정해진 주기로 자동 동작하게 하는 Scheduler에 대해서 알아보려고 합니다. 업무에서는 서비스가 없는 새벽시간에... 고객 유입이 가장 적은시간에 뒷단에서 작업을 돌리는 경우가 많습니다.
그럼 Scheduler를 구동하기 위해서 아래와 같이 진행 해보겠습니다.
- Single Thread Pool
- Multi Thread Pool
1. Single Thread Pool
- 스케쥴 로직을 구현할 class에 @Component annotation 추가
- 구동할 method() 위에 @Scheduled annotation 추가
- configuration annotation이 적용되어있는 class에 @Enablescheduling annotation 추가
우선 Scheduler를 모아놓을 폴더구조를 생성합니다. 거기에 TestScheduler.java를 생성합니다.
[TestScheduler.java]
@Component
public class TestScheduler {
final Logger L = LoggerFactory.getLogger(this.getClass());
@Scheduled(cron = "1 * * * * ?")
public void testCron1() {
L.info("[START] testCron1 - System");
long a = 0L;
for(long i=0; i<10000000000L; i++) {
a += i;
}
L.info("[END] testCron1 - System");
}
}
위의 cron에 적용된 내용은 매 시/분에 1초가 되는 순간에 주기적으로 시작하겠다는 내용입니다. 이 밖에도 fixedRate (정해진 주기), fixedDelay (정해진 지연시간) 등으로 설정이 가능합니다.
위에 보시는 것처럼... 관련 annotation이 2가지가 들어갔습니다. ( Component, Scheduled) 그럼 그다음으로 Configuration을 적용한 아무 class나 들어가서 @Enablescheduling를 추가합니다. 저는 지난 시간에 만들었던 SwaggerConfiguration파일에 적용하겠습니다.
[SwaggerConfiguration.java]
@Configuration
@EnableSwagger2
@EnableScheduling
public class SwaggerConfiguration {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.basePackage("com.example.ayoteralab"))
.paths(PathSelectors.any())
.build();
}
}
[결과]
매분 1초에 Schedule이 시작되었으며... 14~15초 정도 사이로 작업이 완료 되었습니다. 또한 [ scheduling-1]이라는 thread pool 로 작업이 진행되었습니다. 그렇다면, single thread pool일때는 어떻게 동작할까요?? 아마도 한개의 작업이 다 끝나고 다음작업이 진행될 것 입니다.
1-1 Single Thread Pool 동시 진행 시 동작 Test
기존 TestScheduler.java에 동일한 schedule을 하나더 추가하고 동시에 작업을 수행하라고 지정합니다.
[TestScheduler.java]
@Component
public class TestScheduler {
final Logger L = LoggerFactory.getLogger(this.getClass());
@Scheduled(cron = "1 * * * * ?")
public void testCron1() {
L.info("[START] testCron1 - System");
long a = 0L;
for(long i=0; i<10000000000L; i++) {
a += i;
}
L.info("[END] testCron1 - System");
}
@Scheduled(cron = "1 * * * * ?")
public void testCron2() {
L.info("[START] testCron2 - System");
long a = 0L;
for(long i=0; i<10000000000L; i++) {
a += i;
}
L.info("[END] testCron2 - System");
}
}
[결과]
[ scheduling-1]이라는 thread pool 로 모든작업이 진행되었으며, testCron2가 1초가 되는 시점에 동작하고 testCron1은 대기상태에 있다가 종료되는 시점에 연달아서 동작하였습니다. 그렇다면, 여러개 작업들이 제한시간에 schedule되어야 한다면 어찌해야 할까요?? 바로 multi thread pool이 그 해답니다.
2. Multi Thread Pool
Multi Thread Pool을 사용하기 위해서는 관련 Configuration파일을 추가하면 됩니다.
[SchedulerConfiguration.java]
@Configuration
public class SchedulerConfiguration implements SchedulingConfigurer{
private final int POOL_SIZE = 10;
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
ThreadPoolTaskScheduler tpts = new ThreadPoolTaskScheduler();
tpts.setPoolSize(POOL_SIZE);
tpts.setThreadNamePrefix("Ayoteralab-schedule-pool-");
tpts.initialize();
taskRegistrar.setTaskScheduler(tpts);
}
}
역시나 @Configuration을 추가하고 SchedulingConfigurer를 implements해줍니다. 그러면 알람과 함께 configureTasks method를 override하게 됩니다. 그리고 그 밑에, 원하는 thread pool size, name등을 설정해줍니다.
[결과]
위와 다르게 각 testCron1과 testCron2는 매 1초에 동시에 시작되었으며, 서로다른 schedule thread pool을 사용했습니다.
이렇게 single thread 및 multi thread를 이용해서 scheduler를 구성해 보았습니다.
-Ayotera Lab-
댓글