일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- mock
- 서블릿
- 미션
- yml
- AWS
- 트랜잭션
- 우아한세미나
- 레벨2
- CircuitBreaker
- MSA
- 프로그래머스
- 프리코스
- 코드리뷰
- 세션
- 의존성
- 우테코
- Spring Batch
- 백준
- 스프링부트
- Level2
- JPA
- Paging
- JUnit5
- Docker
- AOP
- REDIS
- HTTP
- 스프링 부트
- 우아한테크코스
- 자바
- Today
- Total
늘
[webflux] webclient 이슈 정리 본문
대표적으로 외부 api를 호출하는 방식에 resttemplate이 있는데 이것은 동기 방식을 이용한 방법이고, WebClient가 비동기를 이용한 방식이다. 공식문서를 보면 스프링 5부터는 webClient사용을 더 추천하고 있다. 또한 restTemplate은 곧 deprecated 된다고 한다. 공통점으로는 둘 다 Http client에서 사용된다는 것이다.
RestTemplate
RestTemplate은 Multi-Thread와 Blocking방식을 사용합니다.
Thread pool은 요청자 어플리케이션 구동 시에 미리 만들어 놓습니다.
Request는 먼저 Queue에 쌓이고 가용한 스레드가 있으면 그 스레드에 할당되어 처리됩니다.
즉, 1 요청 당 1 스레드가 할당됩니다.
각 스레드에서는 Blocking방식으로 처리되어 응답이 올 때까지 그 스레드는 다른 요청에 할당될 수 없습니다.
Spring WebClient
Spring WebClient는 Single Thread와 Non-Blocking방식을 사용합니다.
Mono : 0 ~ 1 개의 결과를 처리하기위한 Reactor 객체이다.
Flux : 0 ~ N 개의 결과를 처리하기 위한 Reactor 객체이다
<반환 타입>
Spring WebFlux를 이용하고 있다면 문제가 없지만 Spring MVC기반이라면 반환 값을 객체로 변환해야 하는 과정이 생긴다.
이럴 때 데이터를 받아오기 위해서. block()을 사용하는 경우가 있다.
그렇게 된다면 main스레드에서 처리하기 때문에 사용하면 안 된다.
사용한다면 테스트 때 사용하라고 한다.
Spring MVC/Webflux - Flux, Mono를 사용하는 환경에서는 절대(Never) block을 사용해서는 안된다. 그냥 단순히 controller 메서드에서 reactive type을 넘기는 식으로 진행해야 한다.
대신 완벽한 Reactive 호출은 아니지만 Lazy Subscribe를 통한 Strem 또는 Iterble로 변환시킬 수 있는 Flux.toStream, Flux.toIterable() 함수를 제공하고 있다.
간단한 예제
exchange()는 상태값이랑 헤더랑 바디도 가져오고 - 메모리 누수 가능이 있다.
retrieve()는 응답의 바디만 가져온다.
localhost:8080/v1/events를 호출하면 받아온 api를 통해서 결과가 잘 나온다!
이슈 발생
No serializer found for class com.bunjang.cote.dto.Event and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: java.util.ArrayList[0])
serialize 하는 과정에서 멤버 변수가 private이라서 발생한다고 한다. getter와 setter를 설정해줬는데도 발생해서 의문이다. 생성자도 public으로 해봤지만 계속 발생했다..🤔🤔🤔
해결법
- application.property에 아래의 내용을 추가해주면 된다.
jackson.serialization.fail-on-empty-beans = false
- dto클래스에 JsonAutoDetect를 추가해서 ANY옵션을 주어도 된다.
'백앤드 개발일지 > 스프링부트' 카테고리의 다른 글
[아키텍처] 계층형 아키텍처와 MSA (2) | 2022.02.11 |
---|---|
[스프링 싱글톤] Bean과 Component 차이 (0) | 2022.01.14 |
springboot logback cloudwatch에 보내기 (0) | 2021.12.01 |
[스프링부트] AOP를 이용한 로그파일 설정 & slf4j (0) | 2021.11.07 |
[우아한 세미나]Spring-Boot-Admin & 외부 파일 위치 관리 (0) | 2021.10.04 |