Spring - 비동기 처리 (async)

비동기적 (Asynchronous) 이란 ?

image

비동기는 요청과 결과가 동시에 일어나지 않는 것입니다.

위에서 Synchronous 처리는 다른 처리가 끝나야 다른 task를 시작하기 시작합니다.

반면에 Asynchronous는 다른 작업이 끝나기를 기다리지 않고 또 다른 작업을 수행할 수 있습니다.

Web MVC에서는 많이 활용되고 있지는 않습니다.

Spring에서는 CompletableFuture를 통해 비동기 처리를 할 수 있다.

CompletableFuture

CompletableFuture는 java util에서 제공하는 클래스로 FutureCompletionStage 인터페이스를 Implements합니다.

쓰레드를 직접 생성하지 않고, 미리 저장해둔 thread 관련 configure을 통해 호출할 수 있습니다.

Future

비동기적 연산의 결과를 표현하는 인터페이스입니다.

멀티 쓰레드 환경에서 처리된 데이터를 다른 쓰레드에 전달할 수 있고, Thread-Safe합니다.


Spring의 비동기 처리

Spring MVC 3.2 버전 이후부터 Servlet 3.0 기반의 비동기 처리가 가능합니다.

Spring에서는 annotation을 통해 메서드를 비동기적으로 호출할 수 있습니다.

1. Main 클래스에 @EnableAsync Annotation 추가

비동기 처리를 사용하기 위해서 @SpringBootApplication이 명시된 곳에 @EnableAsync를 추가해 주어야 합니다.

1
2
3
4
5
6
7
8
@SpringBootApplication
@EnableAsync
public class AsyncTestApplication {

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

2. ThreadPoolTaskExecutor 구현

필수적인 것은 아니지만 서버를 개발함에 있어서 traffic을 예상하여 미리 Thread를 할당해주는 방법이 좋다고 생각합니다.

ThreadPoolTaskExecutor 클래스를 통해 Thread Pool의 Max Size, Core Pool Size, Queue Capacity, Thread Name Prefix 등을 설정할 수 있습니다.

Core Pool Size(동시 실행 가능한 쓰레드 개수)에 설정한 쓰레드 풀의 크기를 초과하는 task가 들어오면 Queue Capacity에 task가 쌓입니다.

이 때 Queue Capacity에 최대 Max Pool Size에 설정한만큼 task를 보관할 수 있습니다.

이를 통해 호출된 Thread에는 Async-라는 이름이 붙도록 prefix를 설정해주었습니다.

1
2
3
4
5
6
7
8
9
10
11
12
@Configuration
public class AsyncConfiguration {
@Bean("async-thread")
public Executor asyncConfig(){
ThreadPoolTaskExecutor tpte = new ThreadPoolTaskExecutor();
tpte.setMaxPoolSize(100);
tpte.setCorePoolSize(10);
tpte.setQueueCapacity(10);
tpte.setThreadNamePrefix("Async-");
return tpte;
}
}

3. Service 단에서 사용

메서드에 @Async라는 Annotation을 붙이고, 위에서 지정한 Bean의 id를 통해 사용할 Thread Pool을 설정하였습니다.

서비스 로직(hello)을 작성하여 CompletableFuture를 return하는 메서드에 넣어주었습니다.

여기서 AsyncResult는 비동기처리를위해 Future를 리턴하는 메서드의 method signature로 사용되는 handlerdlek.
- method signature : 메서드 이름과, 파라미터에 관해 약속된 메서드 생성 규칙

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Slf4j
@Service
public class ApiService {

@Async("async-thread")
public CompletableFuture run() {
return new AsyncResult(hello()).completable();
}

public String hello() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(2000);
log.info("Thread Sleeping..");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "service hello";
}
}

이후에 추가적으로 Controller에서 Service Class를 의존성 주입하고, run()메서드를 호출하면 비동기 처리가 가능합니다.

Spring - 비동기 처리 (async)

http://inwoo.github.io/11/09/async/

Author

Inwoo Jeong

Posted on

2021-11-09

Updated on

2021-11-09

Licensed under

You need to set install_url to use ShareThis. Please set it in _config.yml.

댓글