728x90
반응형
SMALL
API 호출 성능테스트를 진행하였다
1. 테스트 준비
공통조건: 외부로 요청하는 get api url은 동일하다.
1.Spring Mvc + RestTemplate
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
@Slf4j
@RequiredArgsConstructor
@Service
public class ApiCallService {
private final RestTemplate restTemplate;
@Value("${rest.fpl.date.url}")
private String testUrl;
public ResponseEntity<String> fpl_date_call_v2(){
log.info(Thread.currentThread().getName());
return restTemplate.getForEntity(testUrl,String.class);
}
}
@RequiredArgsConstructor
@RestController
public class BlockApi {
private final ApiCallService nonBlockService;
@GetMapping("/v2")
public ResponseEntity<String> test2(){
return nonBlockService.fpl_date_call_v2();
}
}
2.Spring webFlux + WebClient
@Bean
public WebClient webClient() {
return WebClient.create();
}
@Slf4j
@RequiredArgsConstructor
@Service
public class ApiCallService {
private final WebClient webClient;
@Value("${rest.fpl.date.url}")
private String testUrl;
public Mono<String> fpl_date_call_v1(){
log.info(Thread.currentThread().getName());
return webClient
.get()
.uri(testUrl)
.retrieve()
.bodyToMono(String.class);
}
}
@RequiredArgsConstructor
@RestController
public class NonblockApi {
private final ApiCallService blockService;
@GetMapping("/v1")
public Mono<String> test1(){
return blockService.fpl_date_call_v1();
}
}
2.테스트 결과
NonBlock
에러메시지
reactor.netty.internal.shaded.reactor.pool.PoolAcquirePendingLimitException: Pending acquire queue has reached its maximum size of 1000
...
reactor.netty.http.client.PrematureCloseException: Connection prematurely closed DURING response
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
*__checkpoint ⇢ Body from GET http://127.0.0.1:10118/ffice/20240305 [DefaultClientResponse]
*__checkpoint ⇢ Body from GET http://127.0.0.1:10118/ffice/20240305 [DefaultClientResponse]
Original Stack Trace:
평군 에러율: 279304/697487 = 40%
평균 TPS: 2375

Block
에러메시지
2024-04-03T17:42:23.351+09:00 ERROR 53544 --- [hwuam-swim-api] [-10117-exec-173] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://127.0.0.1:10118/ffice/20240305": Address already in use: connect] with root cause
java.net.BindException: Address already in use: connect
...
평군 에러율: 71797 / 87376 = 82%
평균 TPS: 866

3. 테스트 결과 분석
- nonblock 은 TPS를 어느정도 유지하는 반면, block은 거의 죽었다시피 중간에 0에 수렴한다.
- 트래픽 증가시 block 이 nonblock에 비해서 2배정도 에러율이 높다.
- nonblock은 테스트시간 3분동안 지속적으로 구동된것에 비해서 block은 20초 정도에 테스트가 중단된다.(거의 통신 두절..)
괜히 Spring 5 부터는 webClient가 채택된것이 아님을 몸으로 느꼈다.
간단한 테스트로만 확인하더라고 성능차이가 확연하다.
여태까지는 주로 restTemplate을 사용했지만, 이젠 webClient를 고려해보자.
728x90
반응형
LIST
'SPRING > 스프링부트' 카테고리의 다른 글
@MockBean vs @Mock,@InjectMocks (0) | 2025.01.06 |
---|---|
Spring에서 request에 대한 검증 방법 2가지 (0) | 2024.05.07 |
동시성 해결방법 (0) | 2024.03.26 |
로컬,개발,운영 yml를 하나로 통합 및 프로퍼티 호출시 @Value의 장단점 및 대체재 (0) | 2023.08.09 |
Prometheus & Grafana & Spring boot 모니티링 하기 (0) | 2023.07.31 |