성능 측정 중 고려할 점
적절한 근거 자료가 갖추어야 하는 내용은 다음과 같다.
- 비슷한 수준의 버전(모두 최신인 게 가장 best) 환경에서 비교가 이루어졌는가?
- 우리가 지향하는 개발 환경과 적합 내지는 유사한 환경에서 비교가 이루어졌는가?
- 유사한 작업을 수행하는 환경(return success만 수행하는 등)에서 비교가 이루어졌는가?
그리고 비교 분석에 추가할 내용으로 권장받은 내용은 다음과 같다.
- 문서화 지향적인 환경에서 개발을 진행할 수 있는가? 일일이 yaml 파일을 작성한다든지 하지 않아도 Swagger API 리스트 등이 출력되는가? 그게 아니라면 어떤 식으로 작업해야 하는가? 혹은 기타 API 명세 자동화 등을 지원하는가?
- Unit Test를 지원하는 방식이 있는가? 가령 Jest 등에 대해 적절한 권고 방식 등을 제공하는가? 그게 아니라면 이를 이용할 수 있는 적절하면서도 저명한 레퍼런스가 존재하는가?
- Mock이나 GraphQL 등을 지원하는가? 도 함께 찾아볼 수 있다면 좋음!
- TypeORM 등은 사용하지 않을 예정이므로 큰 상관은 없을 것 같음. (대신 Mongoose) 근데 ORM은 왜 연산 과정이 일반적으로 더 느린걸까? 그렇다면 성능을 포기하더라도 일반 쿼리로 데이터를 끌어오지 않는 이유가 있는 걸까?😒
성능 측정 방법
https://tech.madup.com/performance_test_tool/
- wrk가 훨씬 가벼워서 그 친구를 채택하기로 했다.
- 다음 사항이 이루어질 예정이다.
- Express, Nest.js(with express), Nest.js(with Fastify Adaptor), Fastify의 속도를 측정. 이때, 각각의 속도 비교는 json 파일에 데이터를 담아 확인하는 방식으로 진행.
- json file은 이곳을 참고한다.
- 버전은 모두 최신으로 맞춘다. express는 4.17.1 버전, fastify는 3.19.2 버전을 사용했다.
- thread는 20개로 유지했고, connection은 100~200 선으로 맞췄다. 1000번 대부터는 socket error가 너무 많이 발생해서 성능 지표로는 부적절할 것이라 판단.
소스 코드는 다음에서 확인할 수 있다.
https://github.com/octavesop/express-and-fastify
성능 지표를 확인하는 법
다음은 json 파일에서 100개의 데이터를 get으로 응답한다.
20개의 스레드, 200 커넥션(스레드 별 10개), 그리고 60초 동안 지속적으로 트래픽을 발생시킨다.
각 단어는 다음을 의미한다.
- Latency 61.21ms 6.23ms 137.15ms 83.77%: 응답시간 평균은 61.21ms, 표준편차는 6.23ms, 최대값은 137.15ms, 표준편차 1 범위에 들어가는 확률은 83.77% (Stdev가 낮을수록 +/- Stdev가 높을수록 응답시간이 안정적이라고 볼 수 있음)
- 196134 requests in 1.00m, 103.06MB read: 1분 동안 196,314번의 요청을 보냈고 103.06MB데이터를 읽음
- Reqeusts/sec: 3263.40: 초당 3,263번의 요청을 보내서 응답을 받음
GET - json(100개의 데이터) :: 200 connection
두 번 정도 실행하여 더욱 빠른 값을 차용했다.
express
Running 1m test @ <http://localhost:3000/books>
20 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 78.87ms 10.90ms 210.42ms 75.95%
Req/Sec 126.97 34.80 202.00 78.78%
151728 requests in 1.00m, 3.50GB read
Requests/sec: 2524.65
Transfer/sec: 59.61MB
Fastify
Running 1m test @ <http://localhost:3000/books>
20 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 35.72ms 5.50ms 107.49ms 69.40%
Req/Sec 279.80 46.96 404.00 70.09%
334574 requests in 1.00m, 7.69GB read
Requests/sec: 5566.33
Transfer/sec: 131.08MB
Nest.js + express
Running 1m test @ <http://localhost:3000/books>
20 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 65.25ms 10.78ms 228.44ms 73.29%
Req/Sec 153.89 39.00 202.00 49.05%
184002 requests in 1.00m, 4.24GB read
Socket errors: connect 0, read 101, write 0, timeout 0
Requests/sec: 3061.69
Transfer/sec: 72.29MB
(의외로 그냥 express만 사용했을 때보다 성능이 우수하다.)
Nest.js + Fastify
Running 1m test @ <http://localhost:3000/books>
20 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 39.10ms 6.84ms 106.84ms 74.83%
Req/Sec 256.85 46.88 656.00 69.47%
306939 requests in 1.00m, 7.06GB read
Requests/sec: 5107.36
Transfer/sec: 120.27MB
(fastify만 사용했을 때보다는 성능이 떨어졌다.)
GET - return undefined :: 200 connection
Express
Running 1m test @ <http://localhost:3000/>
20 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 92.07ms 95.78ms 594.71ms 91.69%
Req/Sec 152.27 49.21 300.00 65.93%
166885 requests in 1.00m, 39.95MB read
Socket errors: connect 0, read 142, write 0, timeout 0
Requests/sec: 2777.45
Transfer/sec: 680.80KB
(적정한 값을 반환하지 않는 경우에는 성능이 느려진 모습을 보여준다.)
Fastify
Running 1m test @ <http://localhost:3000/>
20 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 4.97ms 1.07ms 60.57ms 92.56%
Req/Sec 2.03k 241.40 2.77k 74.88%
2425614 requests in 1.00m, 282.22MB read
Requests/sec: 40390.18
Transfer/sec: 4.70MB
(1.8버전에 비해 개선된 모습을 보여준다.)
Nest.js + Express
Running 1m test @ <http://localhost:3000/>
20 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 18.77ms 3.96ms 105.15ms 89.50%
Req/Sec 536.35 83.84 2.88k 82.48%
640781 requests in 1.00m, 88.61MB read
Requests/sec: 10663.15
Transfer/sec: 1.47MB
- Nest.js + Fastify
Running 1m test @ <http://localhost:3000/>
20 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 5.66ms 1.06ms 42.31ms 89.82%
Req/Sec 1.78k 203.87 3.17k 73.00%
2125027 requests in 1.00m, 247.24MB read
Requests/sec: 35376.44
Transfer/sec: 4.12MB
POST - return JSON[req.params.id] :: 100 connection
- Express
Running 1m test @ <http://localhost:3000/books/3>
20 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 31.26ms 5.64ms 108.03ms 82.13%
Req/Sec 160.66 28.21 383.00 64.77%
192132 requests in 1.00m, 89.60MB read
Requests/sec: 3196.84
Transfer/sec: 1.49MB
- Fastify
Running 1m test @ <http://localhost:3000/book/3>
20 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 7.14ms 1.35ms 55.36ms 89.23%
Req/Sec 705.45 92.62 2.87k 68.12%
843114 requests in 1.00m, 283.03MB read
Non-2xx or 3xx responses: 843114
Requests/sec: 14027.63
Transfer/sec: 4.71MB
- Nest.js + Express
Running 1m test @ <http://localhost:3000/books/3>
20 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 27.31ms 4.94ms 88.03ms 79.19%
Req/Sec 153.12 25.67 451.02 69.27%
192132 requests in 1.00m, 109.12MB read
Requests/sec: 4296.84
Transfer/sec: 2.31MB
- Nest.js + Fastify
Running 1m test @ <http://localhost:3000/books/3>
20 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 13.92ms 2.11ms 69.37ms 83.01%
Req/Sec 722.52 90.66 1.12k 75.96%
863892 requests in 1.00m, 290.00MB read
Non-2xx or 3xx responses: 863892
Requests/sec: 14374.63
Transfer/sec: 4.83MB
의외로 nest.js를 함께 사용했을 때 express의 성능이 보다 높아진 게 인상깊었다.
'DEVELOPMENT > NODEJS' 카테고리의 다른 글
Node.js BASE64로 AWS S3에 이미지 업로드하기 (0) | 2022.04.17 |
---|---|
cookie 데코레이터에서 JWT payload 추출하기 (0) | 2022.04.15 |
cookie 데코레이터에서 JWT payload 추출하기 (0) | 2022.04.08 |
pm2 package.json 명령어 실행하기 (0) | 2022.03.30 |
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: (0) | 2022.02.02 |