1. 동기/비동기 vs 블로킹/논블로킹
1) 동기 vs 비동기
- 요청하는 쪽이 제어권을 언제 돌려받느냐의 차이다.
| 구분 |
동기 (Synchronous) |
비동기 (Asynchronous) |
| 제어권 |
응답이 올 때까지 제어권을 넘겨줌 |
요청 후 바로 제어권을 돌려받음 |
| 의미 |
응답이 올 때까지 다음 작업 못 함 |
응답을 기다리지 않고 다음 작업 수행 |
2) 블로킹 vs 논블로킹
- 호출된 쪽이 제어권을 언제 돌려주느냐의 차이다.
| 구분 |
블로킹 (Blocking) |
논블로킹 (Non-blocking) |
| 제어권 |
작업이 끝날 때까지 제어권을 돌려주지 않음 |
요청을 받자마자 제어권을 바로 돌려줌 |
| 스레드 |
응답 올 때까지 스레드 점유 |
스레드가 멈추지 않고 다른 작업 처리 |
3) Spring에서의 적용
| 조합 |
제어권 흐름 |
예시 |
| 동기 + 블로킹 |
요청하고 제어권 넘김 → 응답 올 때까지 못 돌려받음 |
RestTemplate |
| 비동기 + 논블로킹 |
요청하고 제어권 바로 돌려받음 → 응답 오면 콜백 처리 |
WebClient + Mono |
2. Spring Web vs Spring WebFlux
- Spring에서 웹 요청을 처리하는 두 가지 방식
| 구분 |
Spring Web (MVC) |
Spring WebFlux |
| 처리 방식 |
동기 / 블로킹 |
비동기 / 논블로킹 |
| 스레드 모델 |
요청 1개 = 스레드 1개 |
스레드 몇 개로 수천 요청 처리 |
| 반환 타입 |
일반 객체 (String, DTO 등) |
Mono, Flux |
| 기반 서버 |
Tomcat |
Netty |
| 파일 타입 |
MultipartFile |
FilePart |
| 파라미터 어노테이션 |
@RequestParam |
@RequestPart |
| 학습 난이도 |
쉬움 |
어려움 |
| 사용 상황 |
일반 웹 서비스 |
대용량 트래픽, 실시간, MSA |
3. Mono / Flux
- WebFlux의 반환 타입.
- 데이터를 즉시 반환하지 않고 나중에 줄게 라는 약속이다.
| 타입 |
반환 개수 |
사용 예 |
| Mono<T> |
0 or 1개 |
단건 조회, 저장 결과 |
| Flux<T> |
0 ~ N개 |
목록 조회, 스트리밍 |
Mono<String> result = webClient.get().retrieve().bodyToMono(String.class);
// 지금 당장 String이 아니라 "나중에 String이 올거야" 라는 약속
4. Mono vs String 반환
- WebFlux에서 String을 반환하려면 결국 .block()을 써야 한다.
// String 반환 - 블로킹 발생
public String service(...) {
return webClient.post()
...
.bodyToMono(String.class)
.block(); // 응답 올 때까지 스레드가 멈춰서 기다림
}
// Mono<String> 반환 - 논블로킹 유지
public Mono<String> service(...) {
return webClient.post()
...
.bodyToMono(String.class);
// 스레드는 기다리지 않고 다른 요청 처리하러 감
// 응답이 오면 그때 처리
}
| 구분 |
String 반환 |
Mono<String> 반환 |
| 블로킹 여부 |
블로킹 (.block() 필요) |
논블로킹 |
| 스레드 |
응답 올 때까지 점유 |
응답 오면 그때 처리 |
| 데드락 위험 |
있음 |
없음 |
| WebFlux 장점 |
사라짐 |
유지됨 |
5. WebClient vs RestTemplate vs RestClient
- Spring에서 외부 서버에 HTTP 요청을 보내는 클라이언트
| 항목 |
RestTemplate |
WebClient |
RestClient |
| 요청 방식 |
동기 (Blocking) |
비동기 (Non-blocking) |
동기 (Blocking) |
| 반환 타입 |
DTO 직접 반환 |
Mono<T> / Flux<T> |
DTO 직접 반환 |
| 성능 |
낮음 |
가장 높음 |
중간 |
| 코드 스타일 |
절차적 |
선언적 (반응형) |
절차적 |
| 도입 버전 |
Spring 3.x~ |
Spring 5.0+ |
Spring 6.1 / Boot 3.2+ |
| 현재 상태 |
deprecated 예정 |
권장 (비동기) |
권장 (동기) |
| 추천 상황 |
레거시 유지보수 |
대용량 트래픽, MSA |
일반적인 신규 프로젝트 |
- WebFlux 환경에서는 WebClient 사용한다.
- RestTemplate은 블로킹이라 WebFlux의 논블로킹 장점이 사라진다.