개요
프로젝트 개발의 마무리 단계로 개발한 서비스에 대한 테스트를 진행하였다. 그동안 개발을 해오면서 JUnit과 Mockito를 이용한 통합 및 단위테스트는 많이 진행했지만 외부 도구를 사용해 실제 서버에 올라간 애플리케이션에 대한 테스트를 진행해본 경험이 없어 이번 기회에 테스트를 진행하고 그 과정을 정리해보고자 한다. 해당 글은 테스트를 위한 문서인 테스트 시나리오 작성에 대한 내용을 정리한 글이다.
테스트 시나리오 작성 관련 참고사항
먼저 애플리케이션을 테스트할 수 있는 도구로 아파치에서 제공하는 Jmeter와 네이버에서 제공하는 nGrinder 중 한가지를 선정해야 했다. Jmeter의 경우 nGrinder보다 제공하는 기능이 많았기 때문에 더욱 세부적인 테스트가 가능할 것이라고 판단했지만, 테스트 기간이 짧았고 해당 테스트에서는 얻고자 하는 메트릭의 종류와 테스트 시나리오가 간단할 것이라고 생각했기 때문에 비교적 사용하기 쉬운 nGrinder를 이용하기로 결정했다.
✅ nGrinder 컨트롤러 및 에이전트 실행 환경
nGrinder를 로컬 환경에 설치해서 EC2 서버에 요청을 보내는 방식으로 테스트를 진행했다. 로컬 환경에서 nGrinder를 구동한 이유는nGrinder 컨트롤러와 에이전트를 실행하는 비용도 존재하기 때문에 서버와 동일한 환경에 설치해서 진행하는것은 바람직하지 않다고 생각했다. 또한, 서버 환경에 대한 스펙은 명시하되 컨트롤러 및 에이전트가 실행되는 환경의 스펙은 명시하지 않아도 무관할 것이라고 판단했기 때문에 실제 사용자의 입장에서 요청을 보내는 것으로 가정하고 로컬 환경에 테스트 환경을 구성했다.
✅ 테스트 서버 스펙 결정
테스트를 위한 서버 스펙에 대해 고민하는 과정을 가졌다. 테스트를 진행하는 이유 중 하나를 실제 서버를 배포했을때 특정 스펙에서 어느정도의 트래픽을 안정적으로 처리할 수 있는지라고 판단하기 위함이라고 생각했기 때문에, 가장 낮은 스펙에서 만족할만한 성능을 보일때까지 천천히 올려보기로 결정했다. 하지만, AWS에서 제공하는 가장 낮은 스펙인 프리티어 EC2(t2.micro)의 경우 1vCPU와 1GiB 메모리를 제공하는데 해당 스펙의 EC2를 이용해 테스트를 진행할 경우 기대하는 테스트를 진행할 수 없을 것이라고 판단했다. 스프링 애플리케이션을 실행하기만 해도 메모리를 800MB나 점유하기 때문이다. 따라서 2vCPU와 4GiB 메모리를 제공하는 EC2(t3.medium)를 시작으로 스펙을 천천히 올려서 테스트하는 것으로 결정했다.
상품 검색 기능 부하테스트 시나리오 설계
✅ 테스트 개요
- 상품 검색 기능의 성능 최적화 이전 및 이후 서버에 부하를 일으켜 상품 검색 서비스의 성능이 어느정도 개선되었는지 측정한다. 또한, 최적화 후 서비스에서 어느정도의 트래픽을 견딜 수 있는지 안정성을 측정한다.
✅ 테스트 환경
- 서버는 AWS EC2에서 도커 컨테이너로 구동하는 스프링 애플리케이션을 이용한다.
- t3.medium: amazon linux 2023 ami / 2 vCPU / 4 GiB memory
- Docker 24.0.7, Spring Boot 3.2.1
✅ 테스트 시나리오 설계
- 성능 최적화 전/후의 상품 검색 코드를 서버에 올린 후 10명의 agent로 시작해 100, 1000명 단위로 늘려서 테스트를 진행한다. 요청 Duration은 30분으로 설정한다. 성능 최적화 전/후 상황에서 서버가 감당 가능한 agent의 수를 찾는다.
- Optional: 위 테스트 시나리오와 별도로 테스트 진행시 SQL이 예상한대로 날아가고 있는지(2번의 쿼리가 나가도록 개발했는데 3개가 나간다는 등) 테스트를 진행한다.
- 테스트 주소는 GET: http://13.125.46.61:8080/api/products 로 진행한다.
- 각 요청은 nGrinder Groovy 스크립트를 이용해 페이지 정보(offset, size)와 검색 키워드를 파라미터로 함께 전달한다.
- 성능 최적화 전/후의 TPS, MTT(nGrinder에서 확인 가능)와 서버의 CPU, MEM 사용률을 측정 비교한다.
- CPU, MEM 사용률을 편하게, 그래프화해서 보고싶다면 AWS에서 제공하는 모니터링 기능을 사용해도 괜찮다.
- 하지만, 본 프로젝트를 학습의 목적으로 진행하는 것이기 때문에 EC2 상에서 직접 shell script를 작성해 5초에 한번씩 CPU, MEM 사용률을 기록한다. (간단하게 하려면 도커로 오픈소스를 불러와 사용할 수 있다.)
- 기대하는 테스트 결과
- Postman을 이용해 간단한 테스트를 해봤을때, 최적화 이전에는 평균 1500ms의 응답시간을 보여주고 있고 최적화 이후에는 평균 50ms의 응답시간을 보여주었다. 따라서, 성능 최적화 이후의 테스트에서 TPS, MTT 지표가 더 좋게 나올것으로 예상한다.
- CPU, MEM 사용률의 경우에는 측정 후 분석을 해봐야할 것 같다.
상품 HotDeal 동시성, 정합성 테스트 시나리오 설계
✅ 테스트 개요
- 재고가 100개인 핫딜 상품에 대해 3000명의 사용자가 동시에 (약 7.5초)구매 요청을 하는 시나리오. 동시성 처리 및 데이터베이스 무결성확인을 중점으로한다.
✅ 테스트 환경
- 서버는 AWS EC2에서 도커 컨테이너로 구동하는 스프링 애플리케이션을 사용한다.
- t3.medium: amazon linux 2023 ami / 2 vCPU / 4 GiB memory
- Docker 24.0.7, Spring Boot 3.2.1
✅ 테스트 시나리오 설계
- 3000명의 사용자가 약 7.5초 이내로 3개씩 핫딜 상품구매 요청을 보내는 테스트 진행한다.
- 테스트 주소는 Post: http://13.125.46.61:8080/api/hotdeals/purchase로 진행한다.
- 각 요청은 사용자, 상품 정보를 포함한 Groovy 스크립트를 작성해서 서버에 전송한다.
- 기대하는 테스트 결과
- 재고 관리 정확성: 모든 구매 요청이 처리된 후, 핫딜 상품의 재고 수량이 정확하게 1이 되어야한다.
- 동시성 처리 능력: 시스템은 동시에 들어오는 대량의 요청을 효율적으로 처리할 수 있어야한다.
- 데이터 무결성: 데이터베이스의 무결성이 유지되며, 어떠한 경우에도 재고가 음수가 되지 않아야한다.