개인 플젝 진행 중 자신이 정한 체크리스트를 n일 연속으로 안하면 강제 탈퇴 시키는 기능을 구현 중입니다. 이를 자정에 일괄 처리하기 위해 @Scheduler 어노테이션을 사용하기로 했습니다..
Spring Boot Starter에 기본적으로 의존하므로 특별히 추가하지 않아도 됩니다.
@EnableScheduling // 추가
@SpringBootApplication
public class ToDoListApplication {
public static void main(String[] args) {
SpringApplication.run(ToDoListApplication.class, args);
}
}
Scheduler 정상 작동을 위해 스프링 어플리케이션에 Scheduling을 활성화 해야 한다.
Scheduler를 사용할 Class에 @Component, Method에 @Scheduled를 추가합니다.
이 때 Method는 void 타입으로, 매개변수 사용은 불가능합니다.
@RequiredArgsConstructor
@Component //추가
public class Scheduler {
private final AttendService attendService;
private final TeamManagementService teamManagementService;
@Scheduled(cron = "0 58 23 * * *")
public void saveAttend(){
attendService.saveAll(); //매일 저장
teamManagementService.deleteUser();//매일 체크리스트 몇일 연속 퍼센테지 0퍼인 사람 확인 후 삭제
}
}
@Scheduled 옵션으로는 fixedRate, fixedDelay, cron을 사용하고 각기 다른 방식으로 동작 시킬 수 있습니다.
scheduler 시작하는 시간 기준으로 설정한 간격으로 실행한다.
@Scheduled(fixedRate = 1000)
public void fixedRateScheduler() {
System.out.println(
"Fixed rate - " + System.currentTimeMillis() / 1000);
}
scheduler 끝나는 시간 기준으로 설정한 간격으로 실행된다.
@Scheduled(fixedDelay = 1000)
public void fixedDelayScheduler() {
System.out.println(
"Fixed delay - " + System.currentTimeMillis() / 1000);
}
cron은 개발자가 초, 분, 시, 일, 월, 주, (년)을 설정해 scheduler를 동작 시킨다.
@Scheduled(cron = "0 58 23 * * *") //매일 저장
public void cronScheduler(){
System.out.println();
}
저는 cron이 지정한 시간에 실행됨을 보장하기 때문에 cron을 채택했습니다.
스케쥴러는 기본적으로 1개의 thread를 사용하여 동기 형식으로 진행됩니다. 즉 1번 스케쥴이 끝나지 않으면 2번 스케쥴이 시작시간이 되어도 동작하지 않습니다. 만약 1번과 2번의 스케쥴의 동작 시간이 같은데 동기 형식으로 진행되면 2번의 스케쥴이 제대로 동작하지 않을 수 있습니다.
이런 상황을 방지하기 위해 @Async를 활용하여 다음 스케쥴러가 이전 스케쥴러의 작업이 끝날 때까지 기다리지 않고 자신의 작업을 처리할 수 있게 합니다.
@EnableAsync // Async 활성화
@EnableScheduling
@EnableJpaAuditing
@SpringBootApplication
public class ToDoListApplication {
public static void main(String[] args) {
SpringApplication.run(ToDoListApplication.class, args);
}
}
@Async
@Scheduled(cron = "0 59 23 * * *")
public void saveAttend(){
attendService.saveAll(); //매일 저장
teamManagementService.deleteUser();//매일 체크리스트 몇일 연속 퍼센테지 0퍼인 사람 확인 후 삭제
}
마지막으로, @Async 와 @Scheduled 를 사용하기 위한 설정을 합니다.
@Configuration
public class SchedulerConfig implements AsyncConfigurer, SchedulingConfigurer {
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(Runtime.getRuntime().availableProcessors() * 2);
scheduler.setThreadNamePrefix("MY-SCHEDULER-");
scheduler.initialize();
return scheduler;
}
@Override
public Executor getAsyncExecutor() {
return this.threadPoolTaskScheduler();
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setTaskScheduler(this.threadPoolTaskScheduler());
}
}