1. 작업 스케줄링
특정 시간에 정기적으로 수행해야 하는 비즈니스 작업
작업 스케줄링의 구성요소
작업 스케줄링에 등장하는 3가지 요소가 있습니다. 작업, 트리거, 그리고 스케줄러입니다.
작업: 메서드
스케줄에 맞추어 실행되는 비즈니스 로직입니다.
스프링에서 작업은 메서드로 정의됩니다.
트리거: Trigger 인터페이스
작업은 일정한 시간 간격을 갖고 실행되어야 합니다. 작업의 실행 간격을 관장하는 정책이 트리거입니다.
아래 두 가지는 대표적인 트리거 유형입니다.
1)고정 간격을 지키며 실행
2)cron 표현식에 맞추어 실행
스프링은 Trigger
인터페이스 및 구현체 PeriodicTigger
, CronTrigger
클래스를 제공합니다!
스케줄러: TaskScheduler 인터페이스
스케줄러는 작업을 트리거에 맞추어 실행하되 고유의 실행 전략을 갖습니다.
1) 타이머를 사용한 스케줄링TimerManagerTaskScheduler
는 commonj.timers.TimerManager
를 래핑한 클래스입니다.
Deprecated입니다.
2) 공유 스레드 풀에서 예약 작업을 실행ConcurrentTaskScheduler
와 ThreadPoolTaskScheduler
는 java.util.concurrent.ScheduledThreadPoolExecutor
를 래핑한 클래스입니다.
스프링에서 작업 스케줄링 구성하기
XML 구성
task 네임스페이스
이 네임스페이스 하위 태그를 사용하여
- 작업 스케줄러 빈
- 작업 메서드 & 트리거 정의가 가능합니다.
<beans
...
xmlns:task="http://www.springframework.org/shema/task"
xsi:schemaLocation=..
http://www.springframework.org/schema/task/spring-task.xsd" />
task:scheduler 태그
<task:scheduler id="스케줄러 빈 아이디" pool-size="스레드 풀 사이즈(정수)" />
ThreaedPoolTaskScheduler
스케줄러 빈을 등록합니다.
- id: 생성할 스케줄러 빈의 아이디입니다.
- pool-size:
ScheduledThreadPoolExecutor
가 이용하는 스레드 풀 크기입니다.
task:scheduled-tasks 태그
작업 스케줄러가 담당할 작업들을 열거합니다.
task:scheduled 태그
메서드를 예약 작업으로 정의합니다. 트리거 정책도 설정합니다.
<task:scheduled-tasks schduler="스케줄러 빈 참조">
<task:scheduled ref="서비스 빈 참조" method="메서드명" fixed-delay="10000" />
</task:scheduled-tasks>
- ref: 작업 메서드를 갖고 있는 빈을 지정. 필수 값.
- method: 실행할 메서드 이름. 필수 값.
- trigger: 트리거 인터페이스를 구현하는 빈의 참조. 옵셔널.
- initial-delay: 첫 실행이 일어나기 전 까지 대기할 시간. 단위는 ms. 옵셔널.
- fixed-delay: 한 작업이 끝난 후 지정한 시간만큼 대기하여 다음 작업을 트리거 함. 단위는 ms. 옵셔널.
- fixed-rate: 한 작업을 트리거 한 후 지정한 시간만큼 대기하고 다음 작업을 트리거 함. 따라서 작업들이 큐에 쌓일 수 있고 동시 실행되는 상황도 가능함. 단위는 ms. 옵셔널.
- cron: 크론 표현식을 사용하여 트리거를 정의함. 옵셔널.
어노테이션 구성
@EnableScheduling
Config 클래스에 붙여주면, 스프링은 작업 스케줄러 빈을 색인합니다.
TaskScheduler
혹은ScheduledExecutorService
타입으로 유일한 빈taskScheulder
로 식별되는 빈- 아무것도 찾지 못하면
- 로컬 단일 스레드를 사용하는 스케줄러를 스스로 생성하여 사용함.
이제 우리가 할 일은 예약 작업에 어노테이션을 붙여 주는 것 뿐입니다.
@Scheduled
어노테이션
예약 작업인 메서드에 붙여주는 어노테이션입니다. <task:scheduled>
태그 용법을 준용하면 됩니다.
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {
String CRON_DISABLED = "-";
String cron() default "";
String zone() default "";
long fixedDelay() default -1;
String fixedDelayString() default "";
long fixedRate() default -1;
String fixedRateString() default "";
long initialDelay() default -1;
String initialDelayString() default "";
}
중점 사항
- 스프링은
ThreadPoolTaskScheduler
를 기본적인 스케줄러로 활용하는 것 같습니다.
2. 비동기 작업 선언
@EnableAsync
Config 클래스에 @EnableAsync
를 붙이면 비동기 작업 설정이 가능해집니다.
메서드 비동기 호출 및 반환
메서드에 @Async
어노테이션이 붙은 메서드는 비동기 실행됩니다.
비동기 작업의 반환으로 Future<V>
타입을 내놓을 수 있습니다.
연산된 값을 얻으려면 퓨처의 get()
을 호출하고 실제 값이 가용할 때까지 대기합니다.
public class AsyncService {
@Async
public void asyncTask() {..}
@Async
public Funture<String> asyncTaskWIthReturn() {..}
}
public class Application {
public static void main(String... args) {
AsyncService service = ctx.getBean(AsyncService.class);
service.asyncTask();
Future<String> result = service.asyncTaskWithReturn();
String actualResult = result.get();
}
}
3. 작업 실행
앞서 살펴본 스프링 작업 스케줄링은 TaskScheulder
빈이, @Scheduled
작업들을 주기적으로 실행해 주는 기능이었습니다.
이와 달리, 작업을 단순히 한 번 실행하되 스레드 정책을 적용하고 싶다면 TaskExecutor
를 사용합니다.
상용구 코드
작업 실행자는 Runnable
구현체를 실행합니다. 결국 Task
는 람다식으로 간단히 표현할 수 있습니다.
TaskExecutor taskExecutor = ctx.getBean(TaskExecutor.class);
taskExecutor.executeTask(()-> System.out.println("Task executed"));
작업 실행자 유형
- SimpleAsyncTaskExecutor: 새 스레드에서 작업을 실행함
- SyncTaskExecutor: 작업을 비동기로 실행하지 않고, 호출 스레드에서 실행함
- SimpleThreadPoolTaskExecutor: Quartz와 Quartz가 아닌 컴포넌트가 스레드 풀을 공유하고 싶을 때??
- ThreadPoolTaskExectuor: 스레드 풀을 빌려 작업을 실행할 때.
'웹 개발 > 스프링 프레임워크' 카테고리의 다른 글
[스프링 Web] 웹 API 호출 이야기 - RestTemplate을 사용하는 서비스 구조와 구현 (0) | 2021.12.14 |
---|---|
[스프링MVC] 어노테이션 이야기 - REST와 @ResponseBody (0) | 2021.12.14 |
[스프링 Security] CSRF 토큰 이야기 - csrf() 켰더니 로그아웃이 안 되네? (0) | 2021.12.14 |
[스프링 Security] CSRF 토큰 이야기 - 그래서 개발자는 뭘 하면 되죠 (4) | 2021.12.14 |
[스프링MVC] 서비스 RPC화 이야기 - Deprecated된 HTTP Invoker (0) | 2021.12.14 |