본문 바로가기
  • 실행력이 모든걸 결정한다
Spring Series/Spring Framework

[Spring] Spring의 Task와 Scheduling

by 김코더 김주역 2022. 10. 25.
반응형

1. TaskExecutor

1) TaskExecutor 소개

- 태스크란, 독립적인 쓰레드 안에서 동작하도록 만들어진 오브젝트를 의미한다. TaskExecutor은 이런 태스크를 실행하는 다양한 방법을 추상화한 인터페이스다.

public interface TaskExecutor extends Executor {
    void execute(Runnable task);
}

- TaskExecutor은 JDK의 java.lang.concurrent.Executor를 구현하지 않은 기술의 태스크 실행기에 대한 어댑터를 제공해주고, Spring에 최적화된 방식으로 태스크 실행기를 확장하고 활용할 수 있게 해준다.

- 대부분의 TaskExecutor가 추상화한 기술은 비동기적으로 독립된 쓰레드에서 실행되며, 주로 쓰레드 풀을 사용하는 방식을 사용한다. 이러한 방식이 유용한 것은 사실이다.

 

 

2) Spring이 제공하는 주요 TaskExecutor 구현체

(1) ThreadPoolExecutor

- JDK의 ThreadPoolExecutor와 같은 이름을 가지는 어댑터 클래스로, 가장 손쉽게 사용할 수 있는 대표적인 태스크 실행기다.

- 지정된 크기의 쓰레드 풀을 사용하고, 작업 요청은 큐를 통해 관리된다.

 

(2) SimpleThreadPoolTaskExecutor

- Quartz의 SimpleThreadPool을 이용해 만들어진 태스크 실행기지만 Quartz 스케쥴러와 독립적으로 사용될 수 있다.

 

(3) WorkManagerTaskExecutor

- CommonJ 작업관리자의 태스크 실행기에 대한 어댑터다.

※ CommonJ : JavaEE 환경을 위한 비동기 작업관리자다.  애플리케이션 레벨에서 쓰레드를 관리할 필요 없이 독립적인 작업과 스케쥴 관리가 가능하다.

 

 

2. TaskScheduler

1) TaskScheduler 소개

- 스케쥴링은 일정한 간격이나 정해진 시간에 따라 실행되도록 하는 것이다. Spring은 스케쥴링 기술에 독립적으로 사용할 수 있는 추상화 서비스 인터페이스인 TaskScheduler를 제공한다.

- Trigger 인터페이스를 구현해서 유연한 실행조건을 만들 수도 있다. 대표적으로 CronTrigger 구현체는 유닉스 계열의 서버 환경에서 많이 활용되는 cron 서버의 실행 시간 설정 형식을 그대로 활용할 수 있도록 해준다.

@AutoWired TaskScheduler taskScheduler;
@Resource Runnable task;

public void startTaskScheduler() {
    scheduler.schedule(task, new CronTrigger("0 0/5 14 * * WED"));
}

 

 

2) Spring이 제공하는 주요 TaskScheduler 구현체

(1) ThreadPoolTaskScheduler

- JDK의 ScheduledThreadPoolExecutor 스케쥴러에 대한 어댑터 클래스다. ScheduledThreadPoolExecutor는 쓰레드 풀 방식의 태스크 실행기 기능도 함께 갖고 있다.

 

(2) TimerManagerTaskScheduler

- CommonJ의 TimerManager를 TaskScheduler의 구현체로 만든 것이다.

 

 

 

3. task 전용 태그

- 태스크 실행기와 스케쥴러에 대한 설정을 간편하게 할 수 있도록 하는 전용 태그다.

- 다음과 같이 xml 설정 파일에 task 스키마를 추가해서 사용하면 된다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/task
        http://www.springframework.org/schema/task/spring-task-3.0.xsd">
	...
</beans>

 

1) <task:executor>

- ThreadPoolTaskExecutor 타입의 bean을 등록해주는 태그로 pool-size, queue-capacity 속성을 지정할 수 있다.

<task:executor id="myExecutor" pool-size="30-40" queue-size="50" /> <!-- 풀의 크기는 범위로 지정할 수 있음-->

 

2) <task:scheduler>

- ThreadPoolTaskScheduler 타입의 bean을 등록해주는 태그로, pool-size 속성을 지정할 수 있다. pool-size의 기본값은 1이다.

 

3) <task:scheduled-tasks>, <task:scheduled>

- 일반 bean의 메소드를 태스크로 사용하는 스케쥴을 등록할 때 사용되는 태그들이다. 번거롭게 Runnable 타입의 태스크를 만드는 것이 귀찮을 때 유용할 것이다.

- 아래 예시와 같이 <task:scheduled>의 ref 속성에는 태스크로 사용할 메소드를 포함하는 bean을 지정해주면 되고, <task:scheduled>의 method 속성에는 태스크로 사용할 메소드의 이름을 지정해주면 된다.

<task:scheduled-tasks scheduler="myScheduler">
    <task:scheduled ref="systemService" method="checkSystem" fixed-rate="10000" />
    <task:scheduled ref="resourceService" method="clearAllResources" cron="0 0 18 * * *" />
</task:scheduled-tasks>

 

 

 

4. 어노테이션 방식의 태스크 실행과 스케쥴링

- 태스크와 스케쥴링용 어노테이션으로 @Scheduled, @Async를 소개할 것이다. @Scheduled, @Async를 사용하려면 <task:annotation-driven> 태그를 통해 태스크 실행기와 스케쥴러 bean을 지정해 두어야 한다.

<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>

 

1) @Scheduled

- 태스크로 사용할 메소드에 직접 스케쥴 정보를 부여해서 사용하는 어노테이션이다.

- @Scheduled 메소드는 파라미터를 가질 수 없고 리턴 타입은 void여야 한다.

 

(1) fixedDelay 속성

- 이전 메소드 작업이 끝난 시점부터 일정 시간이 지난 후에 동작하도록 설정한다. 단위는 밀리초다.

@Scheduled(fixedDelay=10000)
public void task() {...}

 

(2) fixedRate 속성

- 이전 메소드가 호출된 시점부터 일정한 시간 간격으로 메소드가 실행되게 설정한다. 단위는 밀리초다.

@Scheduled(fixedRate=10000)
public void task() {...}

 

(3) cron 속성

- cron 형식으로 유연하게 스케쥴을 설정한다.

@Scheduled(cron="0 0 18 * * *")
public void task() {...}

 

 

2) @Async

- 비동기 방식의 태스크로 사용할 메소드에 붙이는 어노테이션이다. 비동기 방식에서는 메소드 내의 작업이 오래 걸리더라도 호출 시에 바로 리턴된다.

- @Async 메소드는 별도의 스레드에서 동작한다.

- @Async 메소드의 리턴 타입은 void 또는 Future 타입이어야 하고, 파라미터는 가질 수 있다.

 

 

● 참고 자료 : 토비의 스프링 3.1 Vol.2

 

반응형

댓글