WebClient 사용법을 학습하던 중 발생한 오류입니다.
WebClient는 비동기식 웹 애플리케이션 구축을 위한 WebFlux의 기능 중 일부로 RestTemplate 클라이언트를 대체하는 새로운 API이며, 비차단 및 반응 웹 클라이언트입니다.
(Blocking 또는 Non-Blocking HTTP 요청을 모두 만들 수 있으며 Spring5 릴리즈 이후로 권장되는 방식입니다.)
public ResponseEntity<?> getTest() {
ResponseSpec responseSpec = webClient.mutate().build()
.get()
.uri("http://localhost:8082/webServer/get")
.retrieve();
ResponseEntity<User> result = responseSpec.toEntity(User.class).block();
return ResponseEntity.ok(result);
}
오류가 발생한 코드입니다.
.bodyToMono() 메서드를 사용하여 Mono<> 타입으로 결과를 받아올 때는 이상 없이 작동하던 코드가 .block() 메서드를 사용하는 부분에서 오류가 발생하였습니다.
이유는 bodyToMono() 메서드는 논블로킹(Non-Blocking)으로 동작하는 반면, block() 메서드는 블로킹(Blocking)으로 동작하는데 에러 메시지처럼 작동하고 있는 Thread는 블로킹(Blocking)을 지원하지 않는다는 것입니다.
오류가 발생한 blockingGet() 메서드입니다. 첫 번째 if 문의 isInNonBlockingThread() 메서드를 통해 작동하고 있는 스레드가 NonBlocking Thread인지 여부를 확인하여 해당 Exception을 던지고 있습니다.
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.6.1'
해당 오류에 대한 해결 방법은 'spring-boot-starter-web' 의존성을 추가하는 것입니다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.projectlombok:lombok:1.18.18'
annotationProcessor('org.projectlombok:lombok')
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// spring-boot-starter-web 의존성 추가
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.6.1'
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-webflux
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-webflux', version: '2.6.1'
}
(의존성 추가 후)
기존 'spring-boot-starter-webflux' 의존성만 추가되었을 때는 Non-Blocking 기반의 Netty가 동작하여 [ctor-http-nio-3] 라는 이름의 스레드가 동작하는 반면에
'spring-boot-starter-web' 의존성을 추가했을 때는 Tomcat으로 실행되며 [nio-8081-exec-2] 라는 이름의 스레드가 실행됩니다.
결론적으로 WebClient를 블로킹(Blocking) 형식으로 사용하고 싶다면 블로킹을 지원하는 스레드 환경에서 작동시켜야 하는 것 같습니다.
WebClient 사용법 학습 중 발생한 오류로 아직 개념 및 사용법을 익히는 중입니다. 때문에 부족한 내용이나 잘못된 부분이 있을 수 있습니다. 해당되는 부분이 있다면 댓글 남겨주시면 확인 후 수정하겠습니다. 미리 감사드립니다.