실무 프로젝트로 배우는 Kotlin & Spring/스프링 WebFlux 이해하기

웹클라이언트

webmaster 2022. 12. 11. 11:22
728x90

RestTemplate

//RestTemplate 은 더이상 사용되지 않는 duplicate 되었다
val url = "http://localhost:8080/books"

val log = LoggerFactory.getLogger(javaClass)

@GetMapping("/books/block")
fun getBooksBlockingWay(): List<Book> {
    log.info("Start RestTemplate")
    val restTemplate = RestTemplate()

    val response = restTemplate.exchange(url, GET, null,
        object : ParameterizedTypeReference<List<Book>>() {})
    //RestTemplate는 코드가 순차적으로 흐르기 때문에 코드를 파악하기는 쉽지만, API를 호출하게된다면, 그 순간 스레드가 Blocking 되기 떄문에 다른일을 하지 못한다.

    val response1 = restTemplate.exchange(url, GET, null,
        object : ParameterizedTypeReference<List<Book>>() {})

    val response2 = restTemplate.exchange(url, GET, null,
        object : ParameterizedTypeReference<List<Book>>() {})
    //복수개의 RestTemplate 가 있다면, 최악의 상황도 나올 수 있기 때문에, 지향하지 않는다

    val result = response.body!!
    log.info("result: {}", result)
    log.info("Finish RestTemplate")
    return result
}
  • RestTemplate는 스프링에서 제공하는 Blocking 방식의 HttpClient이다.
    • 스프링에서 다른 서버와 통신할 경우 사용되고 있다.
    • Spring5부터는 Deprecated 되어 SpringMVC, SpringWebFlux 모두 WebClient 사용을 권고하고 있다.
  • RestTemplate의 문제점으로는 요청을 보낸 서버로부터 응답을 받을  때까지 스레드가 Blocking 되어 다른 일을 하지 못한다.
    • 만약 하나의 API에서 여러 서버의 응답을 받아 결합해서 처리하는 기능(GateWay)이 있는 경우 하나씩 처리하므로 전체적인 응답이 느려지는 문제가 있다.
    • 이런 문제로 인해 복수개의 응답을 처리하는 경우라면 CompletableFuture와 같은 방식을 사용해야 한다.

WebClient

//WebClient 같은 경우 Blocking/Non-Blocking 모두 지원하여, 컨텍스트 스위칭이 줄어 메모리 전략이 가능하며, 동시에 여러서버로 호출이 가능하기 때문에 빠르게 처리가 가능하다는 장점이 있다.
@GetMapping("/books/nonblock")
fun getBooksNonBlockingWay(): Flux<Book> {
    log.info("Start WebClient")
    val flux = WebClient.create()
        .get()
        .uri(url)
        .retrieve()
        .bodyToFlux(Book::class.java)
        .map {
            log.info("result: {}", it)
            it
        }
    log.info("Finish WebClient") //해당 로그가 먼저 찍힌다(non-blocking)
    return flux
}
  • WebClient는 스프링에서 제공하는 리액티브 기반의 Non-Blocking HttpClient이다.
    • Spring5 이후부터 RestTemplate을 대체하여 Non-Blocking 방식, Blocking 방식 모두 사용이 가능하다.
    • WebClient를 사용하면, 스레드가 응답을 기다를 필요 없이 처리할 수 있으므로, RestTemplate 보다 부하를 줄일 수 있고, 여러 서버의 응답을 받아서 처리하는 경우 동시에 여러 서버로 호출이 가능하므로 빠르게 처리가 가능하다.
  • Finish 로그가 찍힌뒤, Book API가 호출되는 것을 확인할 수 있으며, 이는 Non-Blocking으로 동작하는 것으로 확인할 수 있다.
728x90