본문 바로가기

개발/Spring

RestTemplate와 WebClient 비교

현직장에서 java에서 API호출시 기존에는 RestTemplate을 사용하다가 WebClient로 변경을 했습니다. 변경한 이유는 우선 서비스의 속도 개선때문이었는데요,, 간단한 비교 글입니다.

RestTemplate

웹 개발을 하다 보면 url을 호출 할 수 있는 webclient를 이용하여 데이터를 요청하고 해당 데이터 처리를 해야 합니다. spring framework는 이를 위해 RestTemplate과 WebClient를 제공합니다. RestTemplate은 동기이면서 블록킹이며 java servlet api 기반으로 하나의 요청당 하나의 스레드를 사용하는 클래스입니다. 이는 HTTP request가 response를 받을 때까지 해당 스레드는 다른 행위를 하지 못하고 기다려야한다는 뜻입니다. 어떤 서비스 안에 HTTP request가 하나라면 크게 문제가 되지 않을 수 있지만 2개 이상이라면 처리가 많이 느려질 수 있습니다. 또한 서비스에 요청이 늘어나면 응답을 기다리고 있는 스레드가 늘어나서 스레드풀이 가득 차거나 OOM이 발생하게 됩니다. CPU의 context switching도 자주 일어나기 때문에 CPU 성능저하까지 일어납니다. 물론 RestTemplate을 잘 쓰고있었지만 spring에서 이러한 문제를 극복할 WebClient를 출시합니다.

WebClient

WebClient는 비동기이면서 논블록킹입니다. RestTemplate은 응답을 각 HTTP 요청이 응답을 기다려야하지만 WebClient 클래스는 그렇지 않습니다. 

 

예제

RestTemplate과 WebClient 비교를 해보겠습니다.

	@GetMapping("/restTemplateTest")
	public List<String> restTemplateTest() {
		log.info("restTemplateTest started!");
	    RestTemplate restTemplate = new RestTemplate();
	    ResponseEntity<List<String>> response = restTemplate.exchange(
	    		getUri(), HttpMethod.GET, null,
	      new ParameterizedTypeReference<List<String>>(){});
	    List<String> result = response.getBody();
	    result.forEach(res -> log.info(res));
	    log.info("restTemplateTest ended!");
	    return result;
	}
	@GetMapping("/webClientTest")
	public Flux<String> webClientTest() {
		log.info("webClientTest started");
	    Flux<String> resFlux = WebClient.create()
	      .get()
	      .uri(getUri())
	      .retrieve()
	      .bodyToFlux(String.class);
	    resFlux.subscribe(res -> log.info(res));
	    log.info("webClientTest ended");
	    return resFlux;
	}
	@GetMapping("/test")
	public List<String> testMethod() throws InterruptedException{
		List<String> result = new ArrayList<>();
		Thread.sleep(2000L);
		result = Arrays.asList("abc","def","ghi");
		return result;

	}

 

restTemplateTest와 webClientTest라는 get method를 만들어서 test라는 메소드를 호출하는 케이스입니다.

test 안에는 2초간의 sleep이 있어서 리스트를 2초뒤에 반환하는데 RestTemplate은 컨트롤러 종료 로그를 response가 온 뒤에 찍고 WebClient는 response가 오기 전에 찍은 것을 확인할 수 있습니다.

 

'개발 > Spring' 카테고리의 다른 글

Field Injection vs Constructor Injection  (0) 2021.11.09
SIGTERM이란 ?  (0) 2021.03.18