withbible / -deprecated-withbible-server

한국성서대학교 성경졸업고사 퀴즈앱 API서버
1 stars 0 forks source link

23-02-14 부하 테스트 #9

Open kimdev0206 opened 1 year ago

kimdev0206 commented 1 year ago

클라우드 환경(cloudtype, 메모리: 512MB)에 부하테스트를 통해 응답시간이 급격히 늘어나다가 WAS가 죽고 , 그 이후 요청에는 응답을 하지 못하는 상황을 감지하였다.

다음은 WAS가 죽은 이후, 145개 요청을 처리하지 못한 지표이다.

--------------------------------
Summary report @ 16:01:08(+0900)
--------------------------------

errors.ETIMEDOUT: .............................................................. 145
http.codes.200: ................................................................ 611
http.codes.201: ................................................................ 10
http.request_rate: ............................................................. 20/sec
http.requests: ................................................................. 766
http.response_time:
  min: ......................................................................... 45
  max: ......................................................................... 9998
  median: ...................................................................... 5378.9
  p95: ......................................................................... 8024.5
  p99: ......................................................................... 9607.1
http.responses: ................................................................ 621
vusers.completed: .............................................................. 10
vusers.created: ................................................................ 155
vusers.created_by_name.퀴즈: ................................................... 155
vusers.failed: ................................................................. 145
vusers.session_length:
  min: ......................................................................... 1228.1
  max: ......................................................................... 22096.3
  median: ...................................................................... 1495.5
  p95: ......................................................................... 19737.6
  p99: ......................................................................... 19737.6
kimdev0206 commented 1 year ago

다음은 클라우드 환경 관리자측과 대화한 내용이다.

대화의 최종 답변은 다음과 같고,

현재 제공하는 제한적인 CPU/메모리(0.5vCore/512MB) 로 OOM(Out of memory) 이 발생하며 다른 문제도 함께 발생했을 수도 있을 것 같습니다.

해당 플랫폼에서 유료 기능이 생겨 리소스를 늘려보고도 이슈가 지속된다면, 다른 방안을 생각해보아야한다.

kimdev0206 commented 1 year ago

해당 플랫폼 측에서 유료 기능 도입 전에, 한시적으로 리소스를 추가해주었다. (메모리: 512MB4GB) 하지만, 애플리케이션 당 할당된 메모리는 512MB 사용이 고정이었다.

그러면 2가지를 수행해볼 수 있다.

  1. 클러스터링 기법을 통해 서버 애플리케이션을 여러 개 실행하는 것이다.
  2. 반복적으로 가져오는 데이터를 캐싱하는 것이다. 퀴즈 데이터는 빈번히 바뀌지 않기 때문에 충분히 캐싱할 수 있는 코드이다.

조현영 (2020). Node.js 교과서 개정 2판. 서울: 길벗, 526.

kimdev0206 commented 1 year ago

https://github.com/WithBible/withbible-server/issues/9#issuecomment-1556498191 의 2번을 수행한 것만으로도 최대 응답시간을 50% 줄일 수 있었다.

All VUs finished. Total time: 30 seconds

--------------------------------
Summary report @ 15:57:45(+0900)
--------------------------------

errors.ETIMEDOUT: .............................................................. 127
http.codes.200: ................................................................ 572
http.codes.201: ................................................................ 39
http.request_rate: ............................................................. 37/sec
http.requests: ................................................................. 738
http.response_time:
  min: ......................................................................... 46
  max: ......................................................................... 4744
  median: ...................................................................... 788.5
  p95: ......................................................................... 2836.2
  p99: ......................................................................... 4231.1
http.responses: ................................................................ 611
vusers.completed: .............................................................. 28
vusers.created: ................................................................ 155
vusers.created_by_name.퀴즈: ................................................... 155
vusers.failed: ................................................................. 127
vusers.session_length:
  min: ......................................................................... 1430.8
  max: ......................................................................... 9721.6
  median: ...................................................................... 3464.1
  p95: ......................................................................... 7557.1
  p99: ......................................................................... 8520.7

응답시간만 비교해보면 다음과 같다.

``` http.response_time: min: ................................. 45 max: ................................. 9998 median: .............................. 5378.9 p95: ................................. 8024.5 p99: ................................. 9607.1 ``` ``` http.response_time: min: ................................. 46 max: ................................. 4744 median: .............................. 788.5 p95: ................................. 2836.2 p99: ................................. 4231.1 ```

하지만, WAS가 죽어 그 이후 요청을 처리하지 못하는 근본적인 원인은 해결하지 못했다 (응답률: 81.07%82.79%).

또한, 성능 테스트를 통해 지표를 알아본 결과 이벤트 루프를 점유하는 시간은 오히려 더 많아졌다.

![image](https://github.com/WithBible/withbible-server/assets/53007747/624f1d4f-d2c8-4754-9de7-fb589c03ad7e) ![image](https://github.com/WithBible/withbible-server/assets/53007747/10780a66-fcd7-4a5a-8cb8-44602b1e0942)

그 원인을 다음과 같다고 추정한다.

캐싱에 사용하는 value는 약 1500 bytes 정도 되는데, 쓰기 작업에 JSON 문자열화 해두었기 때문에, 읽기 작업마다 자바스크립트 객체로 변환하는 작업이 매번 진행되기 때문이다.

kimdev0206 commented 1 year ago

https://github.com/WithBible/withbible-server/issues/9#issuecomment-1556498191 의 1번 및 2번을 수행함으로써 응답률은 높이되 (82.79%95.69%), 응답시간은 늘어나게 되었다.

All VUs finished. Total time: 40 seconds

--------------------------------
Summary report @ 15:53:49(+0900)
--------------------------------

errors.ETIMEDOUT: .............................................................. 43
http.codes.200: ................................................................ 844
http.codes.201: ................................................................ 104
http.codes.204: ................................................................ 8
http.request_rate: ............................................................. 34/sec
http.requests: ................................................................. 999
http.response_time:
  min: ......................................................................... 42
  max: ......................................................................... 9995
  median: ...................................................................... 2566.3
  p95: ......................................................................... 7557.1
  p99: ......................................................................... 9607.1
http.responses: ................................................................ 956
vusers.completed: .............................................................. 112
vusers.created: ................................................................ 155
vusers.created_by_name.퀴즈: ..................................................... 155
vusers.failed: ................................................................. 43
vusers.session_length:
  min: ......................................................................... 1015.4
  max: ......................................................................... 28764.8
  median: ...................................................................... 24107.7
  p95: ......................................................................... 26643.2
  p99: ......................................................................... 27181.5

응답시간 성능이 떨어진 이유는, 리버스 프록시 용도로 필자가 설정한 nginx 외에 배포 플랫폼에서 클러스터 관리를 위해 내부적으로 nginx가 이미 사용되어 있기 때문이다.

kimdev0206 commented 1 year ago

서버 애플리케이션을 늘려서 응답률을 더 높일 수 있지만, 배포 플랫폼을 무료로 이용하는 상황에서 리소스를 더 추가할 수 없다.

그러면 동일 IP의 중복 요청 수를 제한해볼 수 있다. 요청 수를 제한한다면, 응답시간 성능 저하의 요인이 되는 nginx를 사용하지 않고, 하나의 서버 애플리케이션만 운영하면 된다.