본문 바로가기

cloud

[NCP] Naver Cloud Platform 활용기 - (5) jmeter를 활용한 load test와 pinpoint 모니터링

Naver Cloud Platform 활용기 - (1) server 생성하기
Naver Cloud Platform 활용기 - (2) Cloud DB for MySQL 생성하기
Naver Cloud Platform 활용기 - (3) docker 기반 애플리케이션 배포
Naver Cloud Platform 활용기 - (4) pinpoint를 활용한 시스템 모니터링
Naver Cloud Platform 활용기 - (5) jmeter를 활용한 load test와 pinpoint 모니터링

 

이전 글에서 cloud server, cloud db를 설치하고 application을 구동시켰으며 pinpoint agent를 설정하였다. 이를 통해 db monitoring과 application monitoring이 가능해졌다.

토이 프로젝트를 진행하면서 특정 사용자가 특정 공연의 좌석에 예매하는 프로세스를 만들었다. 이 중에서 예매 행위가 사용자가 가장 몰릴 수 있는 지점으로 가정하고 load test를 진행하고 한계 성능을 측정해보기로 하였다.

 

시나리오: 좌석에 여러 사용자가 동시에 예매를 시도한다.

토이 프로젝트에서는 별도로 n개의 좌석을 만들지 않고 A,S,R,VIP 등 특정 등급의 좌석에 할당된 좌석 수가 있다고 가정하였다. 예를 들어 VIP의 좌석이 10석이라면, 사용자들은 최대 10개까지의 좌석만 예약할 수 있는 구조다.

이때 테스트를 위해 VIP 좌석을 1만개로 잔여 좌석을 늘리고, jmeter를 활용해 동시에 요청을 하도록 만들었다.

JMeter 활용은 다음 글([Java] 테스팅 툴 - JMeter)을 참고한다.

동일 등급의 좌석에 대한 동시성 문제에 대한 해결은 다음 글들(Spring 동시성 문제 해결(비관적 락, Redis 분산락을 적용한 Annotation AOP, 동시성트랜잭션 관련 포스팅)을 참고한다.

초기 클래스 로딩 여부에 따라 성능에 영향이 있을 수 있기 때문에 간단히 요청을 몇개 날려서 웜업을 해주고 요청을 날리기 시작했다. 처음엔 1개, 10개, 50개 정도만 요청을 해보았다. 아래처럼 모두 success 되었고 latency도 30~40ms 정도로 양호했다.

 

이제 100개, 500개의 요청을 보내보도록 한다. 요청을 많이 보낼 때마다 점점 응답시간이 늘어지기 시작한다. 처음 10개 정도는 수십ms 내에서 요청이 처리가 되었지만 100개, 500개로 늘릴수록 최대 수초까지도 소요가 되었다.

 

이제 1,000개 이상의 요청을 보내본다. fail이 발생하고 있다.

 

fail이 발생한 지점을 드래그하여 stack trace를 확인해보면 다음과 같다. redis에서 lock을 획득하는 지점에서 타임아웃이 발생해 실패하기 시작했다. 현재 redis timeout이 5초로 설정되어 있는데, 락을 획득하기 위해 대기하고 있다가 5초가 되어도 락을 획득하지 못하였기 때문에 실패하는 것이다. 한 등급의 좌석에 동시에 여러 요청이 락을 획득하려고 할 때 지연이 되고 있고, 락 획득을 제외한 save() 요청은 대략 5ms 정도의 시간을 소모하고 있다. timeout 5,000ms에 처리 갯수당 5ms 정도를 소모한다고 하면 약 1,000개 정도의 요청이 동시에 처리 가능할 수 있고 일부는 실패할 수도 있는 것을 볼 수 있었다.

 

마치며

이번 글에서는 jmeter로 실제 요청을 만든 뒤 이를 pinpoint에서 확인해보고 추적하는 과정을 살펴보았다. 한 좌석에 대한 다건 요청에 대해서만 테스트를 해보았는데, 특정 시간 동안 여러 좌석에 대해 요청이 들어오는 좀 더 일반적인 시나리오를 작성하여 테스트를 해볼 수도 있을 것이다. 애플리케이션을 구축하고 실제 트래픽을 받아보면 로컬 개발환경과는 전혀 다른 종류의 이슈들이 발생하기 시작하는데, 이를 정확히 분석하기 위해서는 apm의 힘을 빌리는 것이 많은 도움이 되는 듯하다.