티스토리 뷰
728x90
Java에서 WebClient와 FeignClient는 모두 REST API 호출을 위한 HTTP 클라이언트이지만, 설계 철학, 특징, 사용 방식에서 차이가 있습니다.
아래에서 두 클라이언트를 자세히 비교해 보겠습니다.
1. 기본 개념 및 목적
구분 | WebClient | FeignClient |
정의 | 스프링의 리액티브(Non-blocking) HTTP 클라이언트 | 선언형(Declarative) REST 클라이언트 |
지원 방식 | Reactive 방식 | Blocking 방식 (기본적으로 동기 호출) |
사용 목적 | 비동기/논블로킹 HTTP 통신 | 간편한 선언형 HTTP 클라이언트 작성 |
2. 프로그래밍 방식
✅ WebClient (Reactive, Functional)
- 함수형 스타일의 API 제공
- 리액티브 스트림(Reactive Stream)을 기반으로 비동기 요청 처리
- Reactor 기반(Mono, Flux 사용)
예시 코드
WebClient webClient = WebClient.builder()
.baseUrl("https://api.example.com")
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.build();
Mono userMono = webClient.get()
.uri("/users/{id}", 123)
.retrieve()
.bodyToMono(User.class);
✅ FeignClient (Declarative)
- 인터페이스 기반의 선언형 REST 클라이언트 제공
- 내부적으로는 블로킹 HTTP 클라이언트를 사용 (기본적으로 Apache HttpClient나 OkHttp 사용 가능)
예시 코드
@FeignClient(name = "userClient", url = "https://api.example.com")
public interface UserClient {
@GetMapping("/users/{id}")
User getUser(@PathVariable("id") Long id);
}
3. 특징 비교
특징 | WebClient | FeignClient |
방식 | Functional + Reactive | Declarative (Annotation 기반) |
Blocking vs Non-blocking | Non-blocking, Reactive | 기본 Blocking (비동기 옵션 가능) |
기반 기술 | Spring WebFlux (Reactor 기반) | Spring Cloud OpenFeign |
부가 기능 | Backpressure, 고성능 비동기 처리 | 인터페이스 기반으로 코드량 감소, 간결성 |
구현 복잡도 | 중간~높음 | 낮음 (쉽고 빠름) |
학습 곡선 | 다소 높음 (리액티브 이해 필요) | 매우 낮음 (빠른 학습 가능) |
Error Handling | 다양한 Operator를 이용한 유연한 처리 가능 | Exception 기반 간편한 에러처리 |
4. 성능 비교
- WebClient
- Non-blocking 방식으로 리소스를 효율적으로 활용하여 높은 처리량(Throughput)을 보장합니다.
- 지연(Latency) 시간을 효과적으로 관리 가능하며, 대규모 요청 처리에 유리합니다.
- FeignClient
- 동기(Blocked) 방식이 기본이므로 요청이 많아질수록 쓰레드 수 증가로 성능 저하 위험이 있습니다.
- 요청 빈도가 적고 성능보다는 개발 생산성 및 간편성이 중요한 경우 적합합니다.
5. 사용 시나리오 (권장사항)
- WebClient
- 대규모 트래픽 처리 및 높은 성능 요구사항이 있는 마이크로서비스 환경
- 리액티브 프로그래밍 모델(Spring WebFlux)을 사용하는 프로젝트
- 비동기 방식이 필수인 환경 (실시간, 스트리밍 서비스)
- FeignClient
- 비교적 단순한 내부 API 호출을 주로 수행할 때 (예: MSA 환경의 서비스 간 내부 호출)
- 빠른 개발 생산성, 직관적이고 간단한 코드가 중요할 때
- REST 클라이언트를 빠르게 작성하여 관리할 때
6. 최종 선택 가이드라인
조건 | 추천 클라이언트 |
리액티브 환경을 사용하고 성능 중요시 | ✅ WebClient |
높은 처리량, 비동기 요청 필수 | ✅ WebClient |
개발 속도 및 간편성, 빠른 학습 중요 | ✅ FeignClient |
복잡성 감소 및 간단한 인터페이스 유지 필요 | ✅ FeignClient |
기존 블로킹 환경과의 호환성 유지 필요 | ✅ FeignClient |
✅ 리소스 사용량 관점에서 비교
리소스 항목 | WebClient (Non-blocking) | FeignClient (Blocking) | 설명 |
Thread 개수 | 🔵 적음 (적은 수의 쓰레드로 처리 가능) | 🔴 많음 (동시에 많은 요청 처리 시 쓰레드 수 급증 가능) | WebClient는 쓰레드를 적게 사용하면서 동시 요청 처리 능력이 뛰어나 효율적 |
메모리 사용량 | 🔵 효율적 (리액티브 스트림으로 메모리 관리 최적화) | 🟠 보통 (단순 호출 시는 유사하나, 다량 호출 시 쓰레드와 자원 소모 증가) | 다량 호출 시 WebClient가 더 효율적 |
Connection 풀 관리 | 🟢 유연하고 효율적 (Connection 재사용이 우수) | 🟡 일반적인 Connection pool 사용 (Apache HttpClient, OkHttp 등) | WebClient가 더 최적화된 Connection 관리 가능 |
CPU 자원 | 🟢 효율적 (적은 리소스로 비동기 처리) | 🟡 보통 (Context Switching 증가로 CPU 부담 증가 가능) | WebClient가 CPU 효율성이 상대적으로 높음 |
🚩 리소스 소모가 많은 부분: FeignClient
FeignClient는 기본적으로 Blocking 방식이므로 동시에 처리해야 하는 요청이 늘어날수록 쓰레드 풀(thread pool)을 키워야 합니다.
- 다량의 요청이 동시에 오면 각 요청이 처리 완료될 때까지 쓰레드를 점유 → 쓰레드 개수 급증
- 쓰레드 개수 증가로 인해 OS 레벨에서 Context Switching이 빈번해져 CPU 및 메모리 사용량 증가
따라서, 대규모 트래픽 및 많은 동시 요청 처리를 할 경우 FeignClient가 리소스를 더 많이 소모하게 됩니다.
🎯 WebClient가 리소스 소모가 더 적은 이유
WebClient는 **리액티브 프로그래밍(Non-blocking)**을 기반으로 다음과 같은 특징을 가집니다.
- 적은 수의 쓰레드로도 수백~수천 개의 요청을 병렬로 처리 가능
- 비동기 I/O 처리로 쓰레드가 Blocking 되지 않음
- 적은 쓰레드로도 많은 요청을 처리하여 메모리 사용량 감소
- Connection pool 재사용 효율성 높음 → 리소스 관리 최적화
📌 요약 및 추천
요구 사항 | 적합한 클라이언트 |
리소스 효율성, 동시 처리 중요 | ✅ WebClient |
개발 편의성, 소량 요청 처리, 간단한 관리 | ✅ FeignClient |
따라서, 리소스 측면에서 효율적 사용이 중요하면 WebClient를 선택하는 것이 유리합니다.
결론 🎯
- 성능 중심, 리액티브 방식이 필요하면 → WebClient 선택
- 편리하고 빠른 개발 및 유지보수 용이성이 중요하면 → FeignClient 선택
각각의 특성을 이해하고, 본인의 프로젝트 요구사항에 맞게 적절한 클라이언트를 선택하여 활용하세요.
728x90
'Programming' 카테고리의 다른 글
스프링부트 서비스 리소스 절감 최적화 전략 (0) | 2025.03.20 |
---|---|
GraalVM을 사용한 네이티브 이미지 정적 링크 빌드란? (0) | 2025.03.20 |
Kotlin + Spring Boot REST API 예시 (0) | 2025.03.18 |
비동기(Asynchronous) vs. 동기(Synchronous), 블로킹(Blocking) vs. 논블로킹(Non-blocking) (0) | 2025.03.18 |
Spring WebFlux: 비동기 논블로킹 API 개발 (0) | 2025.03.18 |