개발 일기

[Spring Boot] Spring 외부 API 호출 - RestTemplate과 WebClient 본문

Back-End/Spring

[Spring Boot] Spring 외부 API 호출 - RestTemplate과 WebClient

개발 일기장 주인 2024. 12. 9. 19:38

Spring에서 외부 API를 요청하는 방법으로 크게 3가지 정도 있다.

RestTemplate, WebClient, OpenFeign 등이 있는데 이번에 RestTemplate, WebClient 이 두가지에 대해 집중적으로 알아보겠다.


RestTemplate

  • Spring 3.x에서 도입된 동기식 HTTP 클라이언트
  • Multi-Thread, Blocking IO로 동작
  • 현재는 maintenance mode로 개발자에게 WebClient사용을 권장한다.
  • Restful 형식에 맞추어진 템플릿
  • Header, Content-Type등 설정하여 외부 API 호출
  • Http 요청 후 json, xml, String 같은 응답을 받을 수 있다.

RestTemplate 동작 방법 및 문제점

위에서 언급했듯이 RestTemplate은 Multi-Thread 이면서 Blocking IO 방식으로 동작한다.

어플리케이션이 실행되면 Thread Pool에 미리 Thread들이 생성되고 요청이 들어오면 미리 생성해둔 Thread들을 할당한다.

각 쓰레드는 Blocking IO로 할당된 작업을 처리하기 때문에 외부 API를 요청하고 그 응답이 반환될때까지 다른 요청에 할당될 수 없다.

그런데 만약 Thread Pool의 미리 생성해둔 Thread들이 모두 말라버리면 어떻게 될까?

 

문제점

들어온 요청은 유휴 상태의 Thread에게 할당되어야만 처리할 수 있지만 Thread들이 모두 말라버리면 당장 처리될 수 없기때문에 Queue에서 할당되지 못한 작업들이 대기하게 되고 이는 병목 현상으로 이어져 서비스 자체의 성능 저하로 이어진다.

이를 Connection Pool 값 설정을 통해 해결할 수 있지만 하드웨어적 한계가 있을 수 있다.

 

이러한 문제점을 WebClient로 해결할 수 있다.


WebClient

  • Spring 5.x에서 도입된 비동기식 HTTP 클라이언트
  • Single-Thread, Non-Blocking IO로 동작
  • WebFlux기반

 

WebClient 동작 방법

WebClient의 동작 방식은 Node.js와 유사했다.

 

  • 어플리케이션이 실행되면 요청 처리를 위한 Event Loop 기반의 Signle-Thread가 동작한다.(주 Thread)
  • 이때 클라이언트로부터 들어온 요청들이 해당 Event Loop의 Queue에 등록된다.
  • Event Loop에서 각 작업들을 Worker들에게 위임하여 Non-Blocking I/O로 처리된다.(I/O작업을 Non-Blocking방식으로 처리)
    ➜ 외부 API 호출이나 I/O 작업을 처리하는 동안, 해당 작업의 응답이 오기 전까지 다른 요청을 처리할 수 있다
  • Worker가 I/O 작업을 처리한 후 반환된 응답(작업 결과)을 Event LoopCallback한다.
  • 후속 작업이 있는 경우 큐에서 다시 Worker에게 할당되기를 기다리거나 클라이언트로 최종 결과를 반환한다.

이러한 처리 방식을 통해 Non-Blocking 방식으로 처리되며 Event Loop를 활용한 Single-Thread이기 때문에 Thread Pool에 Thread가 마를 일이 없어 RestTemplate의 단점인 스레드 부족으로 인한 병목 현상이 해결될 수 있다.


실제 Boot1은 RestTemplate, Boot2는 WebClient를 사용했을때 성능체크를 한 것이다.

이를 통해 소규모일때는 비슷하지만 동시 사용자가 늘어 대규모 트래픽이 발생할 경우 RestTemplate은 급격하게 성능이 떨어지는 것을 확인할 수 있다.