An open API service indexing awesome lists of open source software.

https://github.com/earlgrey02/webflux-performance-test

Performance Comparison of Spring WebFlux and Spring Web MVC
https://github.com/earlgrey02/webflux-performance-test

kotlin spring

Last synced: 2 months ago
JSON representation

Performance Comparison of Spring WebFlux and Spring Web MVC

Awesome Lists containing this project

README

          

## WebFlux performance test

> **Spring Web MVC와의 비교를 통한 Spring WebFlux 성능 테스트**

본 저장소는 Spring Web MVC와 Spring WebFlux의 성능 비교를 수행하는 테스트에 대한 저장소이다.

## Setup

### Environment

일반적인 개발 환경을 구성하기 위해 대부분의 설정에서 기본값을 사용하도록 했다.
참고로 테스트에 사용된 시스템의 CPU 코어 수는 총 12개이다.

* Spring Web MVC
* Tomcat
* 스레드 풀 크기: 200
* Spring WebFlux
* Reactor Netty
* 이벤트 루프 스레드 개수: 12(CPU 코어 수)
* Reactor
* `ParallelScheduler`의 스레드 풀 크기: 12(CPU 코어 수)
* `BoundedElasticScheduler`의 스레드 풀 크기: 120(CPU 코어 수 x 10)

### Test Case

Apache JMeter를 사용하여 부하 테스트를 수행하며, 모든 테스트는 Cold Start 환경에서 10,000건의 요청을 한 번에 받도록 하는 방식으로 수행했다.

* CPU Bound
* 반복문을 통해 총 10,000,000회의 제곱근 연산(`sqrt()`)을 수행
* I/O Bound
* 데이터베이스로부터 단일 데이터 조회(`SELECT * FROM DEMO WHERE id = 1 LIMIT 1`) 수행

## Result

### CPU Bound




Spring Web MVC
Spring WebFlux


Without Scheduler
With Scheduler




Total Requests
10000
10000
10000


Average Response Time (ms)
1435
2229
1877


Min Response Time (ms)
136
50
85


Max Response Time (ms)
4421
8383
4785


Response Time Std. Dev.
787.49
2824.23
815.68


Error Rate (%)
0.00%
0.00%
0.00%


Throughput (req/sec)
2201.18
1022.39
2085.94


Peak Thread Count
222
46
57

CPU Bound 테스트에서는 **Spring Web MVC가 Spring WebFlux보다 뛰어난 성능**을 보이는 것을 확인할 수 있다.
이는 Spring WebFlux에서는 CPU Bound 작업으로 인해 이벤트 루프 스레드가 차단되면 요청을 더 이상 받을 수 없기 때문이다.
게다가 이벤트 루프 스레드는 기본적으로 CPU 코어 수와 동일한 개수만을 가지는데, 이는 Tomcat의 최대 스레드 수 기본값인 200개에 비해 훨씬 적은 개수이다.
그러므로 Spring WebFlux는 CPU Bound 작업 등의 블로킹 작업에 더 큰 성능 저하를 겪게 된다.

그러나 **Spring WebFlux에서 Reactor의 `ParallelScheduler`를 사용한 경우에는 Spring Web MVC와 비슷한 성능**을 보이는 것을 확인할 수 있다.
이는 CPU Bound 작업이 이벤트 루프와 분리된 전용 스레드 풀에서 처리되기 때문이다.

### I/O Bound




Spring Web MVC
Spring WebFlux


R2DBC
JDBC


Without Scheduler
With Scheduler




Total Requests
10000
10000
10000
10000


Average Response Time (ms)
2927
1065
3225
3148


Min Response Time (ms)
200
199
129
101


Max Response Time (ms)
4700
1585
7978
4995


Response Time Std. Dev.
1185.45
289.32
2363.67
1206.43


Error Rate (%)
0.00%
0.00%
0.00%
0.00%


Throughput (req/sec)
1348.25
2874.39
1006.40
1316.70


Peak Thread Count
223
47
46
166

I/O Bound 테스트에서는 **R2DBC를 사용한 Spring WebFlux가 Spring Web MVC보다 뛰어난 성능**을 보이는 것을 확인할 수 있다.
지연 시간뿐만 아니라 사용한 스레드 수 측면에서도 훨씬 효율적인 결과를 보여주는데, 이는 Spring WebFlux에서는 논블로킹 I/O를 기다리는 동안 이벤트 루프 스레드는 차단되지 않고 계속해서 새로운 요청을 처리할 수 있기
때문이다.

그러나 **Spring WebFlux에서 R2DBC와 같은 논블로킹 I/O가 아닌 JDBC와 같은 블로킹 I/O를 사용할 경우에는 오히려 Spring Web MVC보다 낮은 성능**을 보이는 것을 확인할 수 있다.
이는 앞서 살펴본 CPU Bound 테스트와 마찬가지로, 블로킹 작업이 이벤트 루프 스레드를 점유하면서 전체 처리 성능을 저하시키기 때문이다.
이러한 경우에도 **Reactor의 `BoundedElasticScheduler`를 사용하면 Spring Web MVC와 비슷한 성능**을 낼 수 있음을 확인할 수 있다.

## Summary

테스트 결과를 통해, **Spring WebFlux는 논블로킹 I/O가 많은 환경에서 가장 뛰어난 성능**을 발휘한다는 결론을 도출할 수 있었다.
반면, **CPU Bound 작업이나 블로킹 I/O가 많은 경우에는 Spring Web MVC가 압도적으로 더 나은 성능**을 보였다.
다만, 이러한 상황에서도 **Reactor의 `Scheduler`를 적절히 활용하면 적은 수의 스레드로도 Spring Web MVC에 근접한 성능**을 낼 수 있다는 것으로 결론을 내렸다.