안녕하세요. 이번 글에서는 부하테스트 적용하기에 대해서 포스팅해보겠습니다.
앞선 글을 보며 우리 서비스는 왜 부하테스트를 해야할까, 부하테스트에는 어떤 종류가 있고 어떻게 실행을 계획할 수 있을까에 대해 충분히 고민할 수 있었을 것입니다.
이제 부하테스트를 진행하면서 예상하는 성능, 안정성에 도달하기 위해 개선 - 테스트의 반복적인 과정이 진행될텐데요. 서비스의 부하를 잘 측정하기 위해서는 적절한 부하테스트 도구를 먼저 선정해야 합니다.
1. 부하테스트 도구 선정
서비스에 대한 세밀한 부하테스트를 진행하기 위해서는 시나리오 기반의 부하테스트가 가능한 도구를 사용하는 것이 주요합니다. 저는 JMeter, Ngrinder, K6를 사용해보았고, 각 툴에 대해 제가 느낀 점은 아래와 같습니다.
- JMeter
JMeter는 GUI로 되어 있어 편리한 부분이 있고 성능 검사 후 그래프에 대한 제공도 잘 해주어 가시적으로 정보를 볼 수 있었습니다. 하지만 저같은 경우에는 JMeter 매뉴얼을 보고도 이 서비스를 전부 이용하기는 힘들었습니다. 실제 사용하는 부분은 VUser를 지정하고 몇 분간 어디에 요청을 보내는지
인데, 기능이 너무 많다보니 잘 활용하지 못하겠다 라는 느낌을 받았습니다. CLI도 제공하기 때문에 다양한 기능을 사용하여 부하테스트를 적용하고 싶다면 얼마든 사용해도 좋을 것 같습니다.
- Ngrinder
오픈소스입니다. 그래프도 무료로 확인할 수 있어 테스트가 작동되고 어떤 지표를 보이는지 한 눈에 쉽게 볼 수 있습니다. 또, Groovy 언어를 지원하여 Java 개발자들이 익숙하게 스크립트를 작성할 수 있다는 장점이 있습니다. 하지만 실행하기 위해 두 개의 프로그램이 각각 실행되어야 하고, 이게 한 인스턴스에서 돌기에는 생각보다 큰 자원을 차지하는 것 같았습니다. (부하테스트를 잘 하기 위해 둘을 분리해야 한다는 말을 본 것 같기도 하네요.) Naver의 오픈소스를 사용해보고 싶거나 Rest api 요청으로 테스트 실행을 자동화 하고 싶다면 Ngrinder가 선택지가 될 수도 있을 것 같습니다.
- K6
클라우드를 사용하면 유료입니다. CLI를 통해 무료 서비스를 이용하면 다른 부하테스트 도구에 비해 그래프를 쉽게 볼 수 없다는 게 단점이 되겠네요. 하지만 grafana를 이용하면 아마도? 그래프를 시각화 할 수 있는 것으로 알고 있습니다. 또 명령어에 대한 docs 안내가 잘 되어 있고, Javascript 코드로 작성되기 때문에 시나리오 작성에 크게 어려운 점은 없습니다.
위 세 부하테스트 도구 모두 좋은 도구이고 각각의 장점이 있습니다. 제 생각에는 시나리오 기반으로 부하테스트를 할 수 있고, 내가 정한 목표치만큼 부하를 줄 수 있다면 본인에게 더 편리한 툴을 사용하는 것이 맞는 것 같습니다. 저 같은 경우에는 입문자에게 정말 쉽게 Getting Started를 제공하는 K6를 선택하였습니다.
(1) 내가 원하는 시나리오 대로 (2) 부하를 조정해가면서 (3) 시스템에 충분한 부하를 주고 (4) 어떤 환경에서든 부하를 줄 수 있다면 본인에게 익숙하고 상황에 맞게 사용하기 편한 툴을 선택하세요!
2. 무엇을 테스트 할 것인가?
부하테스트를 하기에 앞서 무엇을 테스트 할 것인지 결정하는 것이 정말 중요합니다.
- 서버에서 정적 리소스를 잘 서빙해주는지?
외부의 영향 전혀 없이 서비스를 제공하는 프레임워크, 서비스 환경 자체에 대한 검증이 필요하다면 로컬호스트에서 정적 리소스를 원하는 기대치만큼의 성능으로 잘 반환하는지 확인해보면 좋을 것 같습니다. 혹은 "Hello World" 정도를 찍어보고 검증을 해볼 수도 있을 것 같습니다.
- DB 연결 + 조회에 대한 검증 (DB 사용, 네트워크 요청 or 로컬호스트)
DB에 연결하고 조회에 대한 부하를 주고 검증을 하려면 운영 환경만큼 더미 데이터를 쌓아두고 반복적으로 조회에 대한 성능을 테스트할 수 있습니다. 이전 테스트인 서버의 리소스만을 사용할 때와는 얼마나 다른 결과를 발생시키는 지, 그 결과의 차이가 유의미하게 크다면 인덱스를 적용해보거나 DB 커넥션 풀을 조정해 볼 수 있을 것 같습니다. 혹은 query를 수정해 볼 수도 있을 것 같습니다. 데이터 갱신보다 조회가 훨씬 많은 서비스라면 캐시 적용까지 고려하여 조회에 대한 성능 개선을 기대해 볼 수 있습니다.
- DB 연결 + CUD에 대한 검증
앞선 테스트와 유사하게 DB에 연결하고 CUD 작업을 진행합니다. 쓰기 작업이 거의 없는 서비스보다, 쓰기 작업이 매우 많거나 종종 쓰기에 대한 부하가 몰리는 서비스를 운영하는 개발자들에게 필수적인 테스트 같습니다. 쓰기 행동을 하기 위한 디스크 I/O 병목을 잘 살피고, 데이터가 잘 갱신되었는지 확인하여 어느정도 성능 / 안정성을 낼 수 있는지 점검할 수 있습니다.
- 외부서비스 연동
외부서비스를 연동 (Oauth, 결제 등)을 테스트 하고 싶다면, 실제 요청 시간과 가깝게 실행되는 임의의 가짜 인스턴스를 띄워 네트워크 요청 / 응답을 위한 리소스를 사용하게끔 만드는 것이 중요합니다. Keep-Alive를 제거하여 반복적인 테스트에서 연결 유지를 하지 않게끔 설정하고, 외부 네트워크를 태우는 것이 필요합니다.
- 사용자 시나리오
앞선 테스트를 통해 병목지점을 발견하고 일부 성능이 개선되었다면 이제 사용자 시나리오를 기반으로 부하테스트를 진행합니다. 일반적으로 사용자가 1회 접속당 어떤 요청들을 보내는지 로그를 통해 확인하고, 사용자 시나리오대로 시스템에 부하를 걸어 사용자가 사용할 때 성능이 잘 나오고 안정적인지 확인할 수 있습니다.
무엇을 테스트할 것인지에 대해서는 제공하는 서비스의 상황에 맞게 잘 선택하여 사용하면 좋을 것 같습니다. 개인적으로 이 지점이 부하테스트 과정에서 가장 많이 고민해야 하는 부분 중 하나라고 생각합니다. 무엇을 어떻게 테스트할 지 정하고 어떻게 개선할지에 대한 계획을 짤 수 있는 지점 같습니다.
3. 어떻게 테스트할 것인가
부하테스트를 실제 운영 환경에 진행할 수는 없습니다. 부하테스트 자체가 최대 부하지점 혹은 목표 성능 유지 등을 점검하면서 서비스에 많은 부하를 주기 때문에 사용자의 서비스 이용에 큰 불편함을 줄 수 있기 때문입니다.
그래서, 테스트 하기위해 운영환경과 동일한 인프라에 동일한 데이터를 가지고 동일한 외부 요청을 보내는 서비스를 통째로 하나 생성하여 부하테스트를 진행합니다. 하지만 인스턴스를 실제 운영환경만큼 띄워서 유지해야하는 것은 그 비용이 어마어마하게 책정될 것입니다. 이런 부분은 다양한 방법으로 개선할 수 있으니 알아보면 좋을 것 같습니다. 배민 성능 테스트 사례
저는 배포 이전에 배포와 거의 유사한 환경에서 운영되는 (추후 Https 까지 적용하여 완벽히 동일하게 할 예정입니다) dev 서버에 부하테스트를 진행했습니다. 앞선 글에서 설명한 Smoke Test, Load Test, Stress Test
중 Load Test를 진행 중에 있습니다. 각 테스트 방법에 대해서는 K6에 상세하게 나와있으니 참조하면 좋을 듯 합니다.
4. 분석
- 부하테스트를 통해 최적의 성능을 찾아가는 과정에서는 Throughput과 Latency에 집중하면 좋을 것 같습니다. RPS와 요청 - 응답 속도가 예상한 부하 상황에서 최적의 성능을 내는지 점검해보아야 합니다. Metric
- Grafana로 지표를 수집하여 시각화 한 결과를 볼 수 있습니다. 어느 지점에서 어느정도의 요청을 수행하는지 확인할 수 있습니다.
top
명령어를 통해 user cpu, kernel cpu를 확인하고 DB, WAS, WS 중 어느 지점에서 CPU를 많이 사용하고 있는지 점검할 수 있습니다.top 확인 방법
vmstat
명령어를 통해 현재 리눅스 서버에 CPU, Memory, Swap, Io, System call 등의 지표를 확인할 수 있습니다. 지표보는법
- 현재 동작하고 있는 application의 Threaddump를 떠서 점검할 수 있습니다. threaddump 보는 법
각종 모니터링 지표들, 로그가 있으니 여러가지를 참고해보면서 어떤 지점에서 병목이 발생하는지, 왜 발생하는지 분석해보는 연습을해보면 좋을 것 같습니다!
'우아한테크코스 4기 > 레벨4' 카테고리의 다른 글
리팩터링(3) - 하다보니 보이는 것들 (2) | 2022.09.25 |
---|---|
리팩터링(2) - 문제 해결하기 (1) | 2022.09.24 |
리팩터링(1) - 필요성과 계획 수립 (0) | 2022.09.24 |
부하테스트 (1) - 부하테스트의 종류와 목적 (0) | 2022.09.09 |
부하테스트 (0) - 고가용성과 부하테스트 (0) | 2022.09.08 |