Web Development/Spring
[Spring] WebClient - 1. 개념 및 기본 설정
graycode
2025. 2. 26. 17:55
WebClient 란
WebClient 는 Spring 5 에서 도입된 비동기적이고 논블로킹 방식의 HTTP 클라이언트이다.
Spring WebFlux 스택의 일부로, Reactive 프로그래밍 모델을 지원한다.
📌 장점
1. Non-Blocking 처리
- 논 블로킹 방식으로 동작하여 시스템 리소스를 효율적으로 사용
- 다수의 API 호출을 동시에 처리
2. Reactive Streams 지원
- Flux 와 Mono 를 통한 반응형 스트림 처리 가능
- 백프레셔(backpressure) 기능을 제공하여 데이터 처리 과부하 제어
3. 유연한 API
- 메소드 체이닝을 통한 직관적인 API 구성 가능
- 다양한 요청 / 응답 변환기 제공
⚠️ 단점
1. 학습 곡선
- Reactive 프로그래밍 패러다임에 대한 이해 필요
- 기존의 동기식 프로그래밍과는 다른 접근 방식 요구
2. 디버깅의 어려움
- 비동기 스택 트레이스가 복잡함
- 에러 추적이 상대적으로 어려울 수 있음
3. 리소스 사용
- 초기 구동 시 더 많은 메모리를 사용
- 단순한 요청의 경우 RestTemplate 보다 오버헤드가 있을 수 있음
✅ 사용 권장 상황
- 대규모 동시 요청 처리가 필요한 경우
- 스트리밍 데이터 처리가 필요한 경우
- 비동기 처리가 필요한 고성능 애플리케이션인 경우
WebClient 기본 설정
WebClient 를 사용하기 위해 필요한 디펜던시를 설정한다. (Maven 기준 SpringBoot 디펜던시 별도)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-netty</artifactId>
</dependency>
📃 WebClientConfig
WebClient 를 구성하고 설정할 클래스를 정의한다.
public class WebClientConfig {
/**
* WebClient 객체 생성
*
* @param httpClient HttpClient
* @param exchangeStrategies ExchangeStrategies
* @return HttpClient
*/
public WebClient buildWebClient(HttpClient httpClient, ExchangeStrategies exchangeStrategies) {
return WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(httpClient))
.exchangeStrategies(exchangeStrategies)
.build();
}
/**
* HttpClient 타임아웃 설정 및 반환
*
* @param timeout int
* @return HttpClient
*/
public HttpClient getHttpClient(int timeout) {
return HttpClient.create()
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, timeout)
.responseTimeout(Duration.ofMillis(timeout))
.doOnConnected(conn -> conn
.addHandlerLast(new ReadTimeoutHandler(timeout, TimeUnit.MILLISECONDS))
.addHandlerLast(new WriteTimeoutHandler(timeout, TimeUnit.MILLISECONDS)));
}
/**
* 인 메모리 버퍼 설정
*
* @param byteCount int
* @return ExchangeStrategies
*/
public ExchangeStrategies getExchangeStrategies(int byteCount) {
return ExchangeStrategies.builder()
.codecs(config -> config.defaultCodecs().maxInMemorySize(byteCount))
.build();
}
/**
* 논 블로킹 IO 구성 시 사용
*
* @return ConnectionProvider
*/
public ConnectionProvider getConnectionProvider() {
return ConnectionProvider.builder("http-pool")
.maxConnections(100)
.pendingAcquireTimeout(Duration.ofMillis(0))
.pendingAcquireMaxCount(-1)
.maxIdleTime(Duration.ofMillis(2000L))
.build();
}
}
아래는 해당 클래스의 각 메소드에 대한 내용을 주석과 함께 설명한다.
📑 getHttpClient
HttpClient 객체를 생성하고 전달된 타임아웃 값을 설정해 반환한다.
public HttpClient getHttpClient(int timeout) {
return HttpClient.create() // HttpClient 생성, 논 블로킹 IO 구성 시 ConnectionProvider 를 create 메소드의 파라미터로 전달
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, timeout) // 서버와의 연결 시도 제한시간
.responseTimeout(Duration.ofMillis(timeout)) // 응답 대기 제한 시간
.doOnConnected(conn -> conn
.addHandlerLast(new ReadTimeoutHandler(timeout, TimeUnit.MILLISECONDS)) // 데이터 읽기 작업 제한 시간
.addHandlerLast(new WriteTimeoutHandler(timeout, TimeUnit.MILLISECONDS))); // 데이터 쓰기 작업 제한 시간
}
📑 getConnectionProvider
논 블로킹 IO 구성 시 사용하며, 생성한 ConnectionProvider 객체를
getHttpClient 함수에 HttpClient.create(ConnectionProvider) 와 같이 전달한다.
public ConnectionProvider getConnectionProvider() {
return ConnectionProvider.builder("http-pool") // 커넥션 풀 구성
.maxConnections(100) // 최대 동시 연결 수
.pendingAcquireTimeout(Duration.ofMillis(0)) // 연결 획득 대기 시간
.pendingAcquireMaxCount(-1) // 대기 중인 최대 획득 요청 수 (-1 일 시 무제한)
.maxIdleTime(Duration.ofMillis(2000L)) // 유휴 연결의 최대 유지 시간
.build();
}
📑 getExchangeStrategies
데이터 교환 정책 설정을 위해, ExchangeStrategies 객체를 생성하고 전달된 인메모리 버퍼 크기를 설정하여 반환한다.
public ExchangeStrategies getExchangeStrategies(int byteCount) {
return ExchangeStrategies.builder() // ExchangeStrategies 구성
.codecs(config -> config.defaultCodecs().maxInMemorySize(byteCount)) // 인메모리 버퍼 사이즈 설정
.build();
}
📑 buildWebClient
HttpClient 와 ExchangeStrategies 를 조합하여 WebClient 객체를 반환한다.
public WebClient buildWebClient(HttpClient httpClient, ExchangeStrategies exchangeStrategies) {
return WebClient.builder() // WebClient 구성
.clientConnector(new ReactorClientHttpConnector(httpClient)) // HttpClient 를 WebClient 와 연결
.exchangeStrategies(exchangeStrategies) // 데이터 교환 전략 설정
.build();
}
📃 WebClientFactory
다음은 WebClient 객체를 서비스 단에서 사용하기 위한 팩토리 클래스를 정의한다.
@Getter
@Service
public class WebClientFactory {
private final WebClient webClient;
public WebClientFactory() {
this.webClient = createWebClient();
}
/**
* WebClient 객체 반환
*
* @return WebClient
*/
public WebClient createWebClient() {
WebClientConfig webClientConfig = new WebClientConfig();
return webClientConfig.buildWebClient(
webClientConfig.getHttpClient(5000), // HttpClient 구성
webClientConfig.getExchangeStrategies(1024 * 1024)); // ExchangeStrategies 구성
}
}
이러한 WebClient 설정 구성을 통해, 리소스의 사용을 효율적으로 관리하고, 안정성을 향상시킬 수 있다.
이후 요청에 대한 핸들링과 API 구성에 대한 내용은 다음 장에 기술한다.
🔗[Spring] WebClient - 2. 요청 핸들링 및 API 구성