김지팡의 저장소
article thumbnail
728x90

 

 

6명이 동시에 요청하면 OOM 발생하는 서비스

영어회화 스터디 서비스를 개발하면서 부하 테스트를 위해 클라우드 환경에 필요한 서비스들을 컨테이너 환경으로 실행했다.클라우드 서비스는 Naver cloud platform의 서비스들을 이용했다.  🛠

happygimy97.tistory.com

 

📌 테스트 배경

 

지난 포스팅에서 50만 건의 데이터를 findAll()로 모두 조회하는 API를 테스트했다가 6명의 유저(vuser)만으로 힙메모리 초과로 OOM이 발생했었다.

 

이를 해결하고자 offset과 pageSize를 설정해 50만 건 중 조건에 맞는 데이터를 pageSize만큼 가져오는 것을 테스트했고, 에러 없이 정상적으로 테스트를 수행하는 것을 확인할 수 있었다.

 

이번 포스팅에서는 vuser를 늘려가며 테스트했던 과정과 이때 만난 에러에 대해서 이야기해보고자 한다.

 

 

🛠️ 테스트 환경 & 시나리오

 

  • 서버 스펙
    • CPU -> 2EA
    • Memory -> 8GB
  • Ngrinder로 테스트
    • 검색 API
      • 원하는 조건, offset, pageSize를 요청 데이터로 가진다.
    • Vuser를 늘려가며 테스트
    • Duration 8분으로 고정

 

📌 테스트 진행

 

반복해서 같은 데이터를 조회하려고 하면 DB 캐싱으로 인한 조회 속도가 빨라지는 경우가 생길 수 있다고 판단하여 offset을 랜덤한 값으로 매번 요청하도록 설정하여 스크립트를 작성하였다.

 

vuser를 조절하면서 테스트를 진행했는데, vuser를 198로 설정해 테스트를 했을 때에는 조회에 실패한 케이스가 전체 케이스의 40%가 나왔고, Ngrinder에서 WARNING 표시를 보여주었다.

 

 

몇 명의 vuser까지 해당 API를 잘 받아내는지를 보고 싶어 vuser를 140과 80으로 설정하여 테스트했다.

 

 

결과는 위처럼 성공이었지만, 자세히 보니 에러가 발생하지 않은 것은 아니었다. vuser를 80으로 했을 때에는 에러가 없었지만 140의 경우에는 여러 번 테스트를 수행한 결과 평균 20% 정도 에러가 발생했다.

 

뒤늦게 안 것이지만, Ngrinder에서 요청 중 에러가 30% 이상이면 WARNING으로 나타내고, 30% 미만이면 SUCCESS로 나타낸다.

 

때문에 평균 20% 정도 에러가 발생하고 있음에도 불구하고 vuser 140의 테스트가 성공으로 나오고 있던 것이었다.

 

Ngrinder에서 제공하는 로그와 spring boot 앱 내에 출력된 로그를 살펴보니 아래와 같이 나와 있었다.

 

java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30000ms (total=10, active=10, idle=0, waiting=16)

 

DB와 통신하기 위해서는 hikari connection pool(hikaricp)이 필요하다.

 

hikaricp가 다 차 있는 상태에서 요청이 들어오면 해당 요청들은 대기 상태(waiting)로 존재하게 되는데, 설정한 5분(30000ms)의 connectionTimeout이 끝날 때까지 active로 넘어가지 못하면 위와 같은 에러가 발생한다.

 

spring boot에서는 기본적으로 최대 커넥션(maximum-pool-size)을 10으로 둔다고 한다. 때문에, active가 10에서 늘어나지 않은 것이고, 더 이상 사용할 커넥션이 없어 에러를 뱉어내는 것이다.

 

이를 해결하기 위해서 pool size를 늘려보기로 했다.

 

 

📌 maximum-pool-size 늘리기

 

vuser를 20, 30, 50까지 늘려가며 다시 Ngrinder를 통해 테스트를 진행했다.

 

에러 비율은 확실히 낮아졌으나 여전히 에러가 존재했고, vuser를 198로 설정해서 테스트했을 때에는 여전히 에러 비율이 30% 이상이었다.

 

 

 

🧑‍💻 고찰

 

vuser를 198로 설정하고 테스트를 진행했을 때에는 TPS 3.5에 평균 응답 속도(Mean Test Time)가 31,143ms(약 31초)의 성능을 보여주고 있었다.

 

 

pool size를 더 늘려보는 것도 생각해 보았지만 응답 속도가 빠르지 않다면 maximum-pool-size를 아무리 늘린다고 해도 에러가 생길 수밖에 없다고 생각했다. 

 

마치 테이블은 많은데 회전율이 낮은 가게 같달까..? 😲

 

게다가, pool-size 자체를 많이 늘리는 것도 DB와의 커넥션을 늘리는 것이기에 DB 성능에 영향을 줄 것이라 판단했다.

 

때문에, 응답 속도 개선을 우선적으로 해야겠다고 생각했다.

 

다음 포스팅에서는 속도 개선을 위해 무엇을 어떻게 왜 했는지에 대해서 이야기해 보겠다.

728x90

'TIL' 카테고리의 다른 글

offset 기반 페이징 방식의 단점  (0) 2025.01.08
서버 진화 ~~~ (서버 스케일업)  (0) 2025.01.07
6명이 동시에 요청하면 OOM 발생하는 서비스  (0) 2025.01.07
Subnet 이해하기  (0) 2024.12.21
VPC 이해하기  (1) 2024.12.14
profile

김지팡의 저장소

@김지팡

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!