[백업][가리사니] spring job scheduler
cron, java, spring

이 문서는 가리사니 개발자 포럼에 올렸던 글의 백업 파일입니다. 오래된 문서가 많아 현재 상황과 맞지 않을 수 있습니다.

크론 / 스케줄러 (배치) 시리즈

서론

스프링에 잡 스케줄링을 하는 방법에 대해서 설명해보겠습니다. 우선 용어정리와 크론 표현식에 대해서 알아보고 싶다면 아래 링크를 참고해주세요.

스프링에서 잡 스케줄러 종류

스프링에서 사용할 수 있는 잡 스케줄러는 스프링 스케줄러와 쿼츠가 있습니다. 스프링 스케줄러 : [https://spring.io/guides/gs/scheduling-tasks/ 쿼츠 스케줄러 : [http://www.quartz-scheduler.org/ 둘에대한 특별한 장/단점을 찾지 못하여 편하게 쓸 수 있는 스프링 스케줄러로 설명을 하겠습니다.

스프링 스케줄러 예제

  • @EnableScheduling 로 스케줄러를 사용한다고 선언합니다.
@Configuration
@EnableScheduling
class SchedulingConfiguration {
}
  • 잡을 만들어보겠습니다.
@Service
public class TSchedule {
	@Scheduled(cron="0/10 * * * * ?")
	public void execute() {
		System.out.println("10초마다 출력");
	}
}
  • 결과 : 10초마다 "10초마다 출력"이 표시됩니다.

실무 이용시 팁

1. 잡(배치)를 직접 실행해야하는 경우.

  • 일반적으로 배치가 돌다가 오류가 났는데, 급하게 다시 돌려야하는 배치의 경우입니다. @Service 를 붙여 만들었기 때문에 단순히 @Autowired 로 사용합니다.
@Autowired TSchedule tSchedule;

@RequestMapping("/admin/job/TSchedule")
String tSchedule() {
	tSchedule.execute();
	// ... 생략
}

바로 @Autowired 하여 동일하게 실행시킬 수 있습니다.

2. 개발하는 배치를 제외하고는 돌릴 수 없거나(환경부재) 돌리면 안되는 경우.

개발서버에선 해당 잡을 받아줄 연계장치가 없거나 쓸대없이 돌면 안되는 경우가 있습니다. (특히 로컬) 이런경우는 아래와 같이 처리할 수 있습니다.

2-1. 모든 잡 스케줄러 제거 (덮어쓰기)
@Configuration
@EnableScheduling
class SchedulingConfiguration implements SchedulingConfigurer {
	@Override
	public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
		if (로컬? 개발서버?) {
			// set 을통해 기존 설정을 모두 날려버렸습니다.
			taskRegistrar.setCronTasksList(Collections.emptyList());
		}
	}
}

그리고 직접 실행합니다. 다만 개발중에도 몇분에 한번씩 돌아야하는 경우가 있습니다.

2-2. 수동으로 추가하기 (덮어쓰기)
  • 물론 제대로 하려면 이 부분은 별도로 빼둬야할 것 같습니다.
@Configuration
@EnableScheduling
class SchedulingConfiguration implements SchedulingConfigurer {
	@Autowired TSchedule tSchedule;

	@Override
	public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
		if (로컬? 개발서버?) {
			// 리스트 생성
			List<CronTask> list = new ArrayList<>();

			// @Autowired tSchedule 를 직접 넣어주고 시간도 재설정
			// 물론 리플렉션을 통해 시간을 가져올 수도있지만 보통 로컬에서
			// 따로 돌릴 정도면 기존의 시간을 쓰지않는 경우가 대부분이라
			// 이렇게 설정했습니다.
			list.add(new CronTask(() -> tSchedule.execute(), "0/5 * * * * ?"));

			// 모든 스케줄 덮어쓰기
			taskRegistrar.setCronTasksList(list);
		}
	}
}