IT/자바, 스프링

스프링 부트에서 비동기로 작업하기

thesse 2022. 1. 10. 10:20
300x250
반응형

request로 들어온 요청을 처리하는데 시간이 오래 걸리는 작업이 있을 경우

응답을 보내주는 데 수분에서 수십분이 걸린다면

사용자 입장에서는 답답함을 느끼고 서비스를 이용하지 않을 수 있다.

 

따라서 시간이 오래 걸리는 작업은 우선 응답을 바로 보내주고

시간이 오래 걸리는 작업은 다른 스레드에서 비동기로 처리하고자 한다.

 

 

 

스프링 부트에서는 @Async 어노테이션을 통해 비동기 작업을 처리할 수 있다.

@Async를 사용하기에 앞서 설정파일을 만들어줘야 한다.

@Configuration
@EnableAsync
public class AsyncConfig extends AsyncConfigurerSupport {

    @Override
    public Executor getAsyncExecutor(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);    // 기본적으로 실행을 대기하고 있는 Thread 개수
        executor.setMaxPoolSize(10);    // 동시 동작하는 최대 Thread 개수
        executor.setQueueCapacity(500); // MaxPoolSize를 초과하는 요청이 Thread 생성 요청시 해당 내용을 Queue에 저장하고, Thread 여유자리 발생하면 하나씩 꺼내서 동작
        executor.setThreadNamePrefix("thesse-async-"); // 스프링이 생성하는 Thread의 접두사 지정
        executor.initialize();
        return executor;
    }

}

CorePoolSize는 슬립 걸린채로 대기중인 스레드 개수. 요청이 들어오면 빠르게 동작할 수 있지만 이걸 크게 잡으면 메모리 소모가 크다.

MaxPoolSize는 스레드풀 내에 스레드를 위해 마련해둘 자리의 개수. 아무런 작업이 없을때는 슬립걸린 스레드 두개와 빈자리 8개가 있을 것임

 

 

 

 

 

그리고 서비스 클래스에서 원하는 메소드에 @Async 어노테이션을 달아준다.

 * @Async 어노테이션은 public 메서드에서만 동작한다. 

 * 같은 클래스 안에 있는 메서드를 호출할 때는 동작하지 않는다.

    @Async
    public void asyncTest() {
        try{
            log.info("async work start");
            Thread.sleep(5000);
            log.info("async work finish");
        } catch (InterruptedException e){
            e.printStackTrace();
        }
    }

 

 

그러면 아래처럼 응답은 485ms만에 도착하지만 async 작업은 5초 뒤에 끝난다.

스레드 이름은 설정파일에서 지정한대로 thesse-async-1로 되어있다.

 

 

 

300x250
반응형