[Spring] RestTemplate으로 비동기 처리해보기

신창호·2024년 1월 27일
0

Spring

목록 보기
2/9

❓그럼 WebClient가 없고, RestTemplate만 있었던 시기에는 비동기처리가 불가능 했던 걸까?

이 질문의 답변은 당연히 아니다.

  • 애초에 RestTemplate은 기본적으로 HTTP 요청을 보내고 응답을 받는 데 사용해왔고, RESTful API 호출하기 위해 매번 세팅값을 만들어야하는 불편함에서 만들어진 Template이다. 비동기적인 동작은 고려했던것이 아니다.

  • 그렇기에 비동기처리를 위해 쓰레드(업무를 처리해주는 얘)를 늘려서 동시에 동작하게 만드는 것이다.
    이런 쓰레드를 보통 관리하는 것이 쓰레드풀이라는 것이다.

쓰레드

  • 프로세스(처리되어야될 일) 내에서 실행되는 독립적인 실행 단위를 말한다.
  • Java, Spring에서 자주쓰이는 Main()메소드도 메인 쓰레드(Main Thread)에 의해 실행이 된다.
  • 여러 Thread를 동시에 실행할 수도 있는데, 이러면 프로그램의 처리속도를 향상시킬 수 있기때문이다.
    • 다만, 그만큼 리소스를 잡아먹어야한다.
    • 그렇기때문에, 필요할때만 Thread를 늘리고, 줄여주고 하면서 최대한 효율적이게 사용하는게 중요하다.

하지만, Tread클래스를 만들어 사용한다던가, Runnable 인터페이스를 구현한다던가등이 마저도 엄청 번거로운 코드 작업이 되기 때문에, 좀 편하게 쓰라고 라이브러리를 만들어준다.

java.util.concurrent 패키지

Java에서 제공하는 동시성(Concurrency) 라이브러리로 멀티스레딩 프로그래밍을 할때 사용하기 좋은 클래스와 인터페이스를 모아져 있다.

Executor

  • 쓰레드의 생성과 관리를 담당하는 인터페이스로 execute(Runnable) 메서드를 통해 작업을 스레드에 할당한다.

ExecutorService

  • Executor 인터페이스를 확장한 인터페이스
  • 스레드 풀을 관리

ThreadPoolExecutor , ScheduledThreadPoolExecutor

  • 위 인터페이스의 구현체이다.

Future

  • 비동기 계산의 결과를 나타내는 인터페이스
  • 비동기처리가 완료되었다면 결과를 여기에 담아 가져올 수 있다.

CompletableFuture

  • Future 확장형으로 추가 기능을 제공
    • Future의 경우, 작업이 완료될때까지 블로킹(대기함)해야되지만
    • CompletableFuture의 경우, 이전 작업의 완료와 상관없이 논블로킹(대기안함)한다.
  • 비동기 실행
    • Future는 결과만 저장할 뿐, 비동기적으로 실행할 수 있는 메소드가 없다.
    • 하지만, CompletableFuture는 supplyAsync, runAsync 등의 메소드로 주어진 작업을 비동기적으로 처리할 수있다.

이 외에도 다양한 비동기적처리를 도와주는 기능이 있다.

❓ 그럼 RestTemplate으로 비동기처리는 어떻게 하는 건데?

Rest API 비동기적 처리하기

내가 알아본 바로는 크게 2가지 방법이 있다. 순수 java로 하는 방식과 Spring Framework에서 제공하는 것을 활용한 방식!(WebClient는 RestTemplate이 아니니 논외)

CompletableFuture사용하기

  • 자바8부터 추가된 CompletableFuture을 사용하면 쉽게 비동기처리가 가능하다.
CompletableFuture<ResponseEntity<String>> future = 
   CompletableFuture.supplyAsync(() ->    
       restTemplate.getForEntity("https://example.com/api/v1/users", String.class));

// 비동기 요청이 완료되기를 대기합니다.
ResponseEntity<String> responseEntity = future.get();

AsyncRestTemplate

  • AsyncRestTemplate은 Spring Framework에서 제공하는 RestTemplate의 비동기 버전으로, HTTP 요청을 비동기적으로 처리할 수 있었다.
  • Spring 5이후 부터론 deprecated 되어 사용할 수 없다.(WebClient를 쓰라고 권장되고 있다.)

추가적인 처리

위까지 하게되면 기본적으로 설정된 쓰레드 규칙에 맞춰 비동기적으로 처리가 된다.
하지만, 나는 전에 요청받는 API서버 측에서 요청 제안을 걸어 너무 많은 제안을 넣으면 안되는 상황이였고, 그렇게된지라 어쩔수없이 쓰레드를 조정하여 요청수를 조정해야됐다.

  • Executors.newFixedThreadPool()을 통해 손쉽게 쓰레드풀의 량을 조정할 수 있었다.

CompletableFuture사용하기

ExecutorService executorService = Executors.newFixedThreadPool(4); // 생성
CompletableFuture<ResponseEntity<String>> future =
    CompletableFuture.supplyAsync(() ->
        restTemplate.getForEntity("https://example.com/api/v1/users", String.class),
        executorService); // 인자에 추가

//..중간 생략
executorService.shutdown(); // 닫아줌
  • 물론 사용을 완료해서 닫아주기만하면 간단하게 쓰레드를 조정할 수가 있었다.
  • 이러한 작업을 별도의 클래스를 만들어 빈에 등록하고 필요할 때마다 어노테이션으로 처리해줄 수도 있다.
profile
한단계씩 올라가는 개발자

0개의 댓글