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 |