기업프로젝트에서 캐시서버를 만들면서 서버 간의 통신이 필요하게 되었다.
보통의 웹과 서버의 통신이 아닌, 서버와 서버끼리의 통신을 위해 찾아보게 되었다.
동기와 blocking, 비동기와 Non-blocking은 다르다.
이 두가지로 통신을 할 수 있다
여기서 더 좋다고 하는 WebClient에 대해 알아보겠다.(추가로 UriComponentsBuilder => URI 조립)
기존의 Spring에서는 HTTP 요청을 할 때 RestTemplate을 사용했다.
하지만 버전이 새로 나오면서 WebClient를 강력히 권고하고 있다.
WebClient의 특징은 다음과 같다.
implementation 'org.springframework.boot:spring-boot-starter-webflux'
작성방법
Static factory를 통하 WebClient 생성
WebClient.create();
추가적인 작업을 위해서는 Builder클래스를 통해 생성하는 것이 좋다.
@Configuration
public class WebClientConfig {
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory();
HttpClient httpClient = HttpClient.create()
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000); // HttpClient 총 연결 시간: 10초
@Bean
public WebClient webClient() { // WebClient 인스턴스를 생성하기 위한 Bean 설정
return WebClient.builder()
.uriBuilderFactory(factory)
.baseUrl("http://mainHost:8080") // WebClient의 기본 URL 설정
.codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(2 * 1024 * 1024)) // 응답 데이터를 저장하기 위한 최대 메모리를 2MB로 제한
.clientConnector(new ReactorClientHttpConnector(httpClient)) // WebClent에 대한 클라이언트 커넥션 설정
.build();
}
@Bean
public ConnectionProvider connectionProvider() { // 커넥션 풀에서 연결을 관리하는데 사용
return ConnectionProvider.builder("http-pool")
.maxConnections(100) // 커넥션 풀의 개수
.pendingAcquireTimeout(Duration.ofMillis(0)) // 풀에서 커넥션을 얻기 위해 기다리는 최대 시간
.pendingAcquireMaxCount(-1) // 풀에서 커넥션을 가져오기 위한 시도 횟수
.maxIdleTime(Duration.ofMillis(1000L)) // 연결이 제거되기 전에 풀에서 유휴 상태를 유지하는 시간
.build();
}
}
들어가기 앞서, Response를 받기 위한 방법은 2가지가 있다
retrieve() : repsonse를 받아 디코딩하는 가장 간단한 메소드
exchange() : 5.3버전에서 deprecated되었으며, exchangeToMono 혹으 exchangeToFlux를 사용하자
return webClient.get()
.uri("")
.retrieve()
.bodyToMono(String.class)
.log()
.block();
GET에서는 RequestBody를 제공 X
return webClient.post()
.uri("")
.bodyValue(body)
.retrieve()
.bodyToMono(String.class)
.log()
.block();
return webClient.delete()
.uri("")
.retrieve()
.bodyToMono(String.class)
.log()
.block();
DELETE에서는 RequestBody를 제공 X
return webClient.put()
.uri("")
.bodyValue(body)
.retrieve()
.bodyToMono(String.class)
.log()
.block();