@Scheduled 사용법

개발하는 구황작물·2023년 1월 15일
0

개인 프로젝트

목록 보기
8/9

개인 플젝 진행 중 자신이 정한 체크리스트를 n일 연속으로 안하면 강제 탈퇴 시키는 기능을 구현 중입니다. 이를 자정에 일괄 처리하기 위해 @Scheduler 어노테이션을 사용하기로 했습니다..

Dependency

Spring Boot Starter에 기본적으로 의존하므로 특별히 추가하지 않아도 됩니다.

Scheduling 활성화

@EnableScheduling // 추가
@SpringBootApplication
public class ToDoListApplication {

	public static void main(String[] args) {
		SpringApplication.run(ToDoListApplication.class, args);
	}

}

Scheduler 정상 작동을 위해 스프링 어플리케이션에 Scheduling을 활성화 해야 한다.

@Scheduled 사용

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을 사용하고 각기 다른 방식으로 동작 시킬 수 있습니다.

fixedRate

scheduler 시작하는 시간 기준으로 설정한 간격으로 실행한다.

@Scheduled(fixedRate = 1000)
    public void fixedRateScheduler() {
        System.out.println(
        "Fixed rate - " + System.currentTimeMillis() / 1000);
    }

fixedDelay

scheduler 끝나는 시간 기준으로 설정한 간격으로 실행된다.

@Scheduled(fixedDelay = 1000)
    public void fixedDelayScheduler() {
        System.out.println(
        "Fixed delay - " + System.currentTimeMillis() / 1000);
    }

cron

cron은 개발자가 초, 분, 시, 일, 월, 주, (년)을 설정해 scheduler를 동작 시킨다.

    @Scheduled(cron = "0 58 23 * * *") //매일 저장
    public void cronScheduler(){
        System.out.println();
    }

저는 cron이 지정한 시간에 실행됨을 보장하기 때문에 cron을 채택했습니다.

@Async

스케쥴러는 기본적으로 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퍼인 사람 확인 후 삭제
    }

@Configuration

마지막으로, @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());
    }
}
profile
어쩌다보니 개발하게 된 구황작물

0개의 댓글