주문 동시성 테스트 - 설계
서론
개인 프로젝트로 진행하고 있는 Naga에서 동시에 여러 요청이 들어왔을 때 데이터 정합성을 지키는 방법에 대해서 학습하기 위해 주문 동시성 테스트를 진행하려고 한다. 해당 포스팅은 동시성 테스트 설계 내용을 다룬다.
본론
환경
테스트 환경은 아래와 같다.
- OS : MacBook Air 15 (M3, 16GB, macOS Tahoe)
- Java 21 / Spring Boot 3.5.16 / MySQL 8.4
목표
동시성 테스트에서 이뤄야할 목표는 아래와 같다.
- 한정된 수량에 대해서 사용자는 1개의 물품만 살 수 있음
- 정확히 한정된 수량만큼 주문이 생성되어야 함
여려 명의 사용자가 동시에 주문을 요청했을 때, 정확히 제품의 수량만큼 주문이 생성되어야 한다. 또한, 제품의 수량이 생성된 주문 만큼 감소되어야 한다.
현재 주문 플로우
Naga 프로젝트의 주문 플로우는 아래와 같다.
- 요청값으로 productId와 quantity를 넘김
- Order, OrderItems를 생성 후 Product의 quantity를 요청으로 넘어온 quantity만큼 감소
발생할 수 있는 에러 상황은 아래와 같다.
- Product의 status가 품절
- Product의 quantity가 요청 quantity보다 적을 경우
테스트 시나리오
테스트 시나리오는 크게 3가지로 구성했다.
- 정합성 검증
- User : 300
- Product quantity : 100
- 정확히 100개의 Order가 생성되어야 함
- 극단 케이스
- User : 100
- Product quantity : 1
- 정확히 1개의 Order가 생성되어야 함
- 부하
- User : 1000, 10000
- Product quantity : 100
- 정확히 100개의 Order가 생성되어야 함
- 락 대기 시간, 응답 시간 등 성능 관찰
여기서 모든 주문의 quantity는 1이다. 정합성 검증 시나리오와 극단 케이스에서는 데이터 정합성을 검증하기 위한 방법을 학습하며, 부하에서는 User의 수를 점점 늘리면서 관찰 가능한 수치를 보고 각 방법에 대한 장/단점을 파악할 것이다.
테스트 도구
테스트 도구는 k6와 JMeter를 비교했다.
- JMeter
- 장점
- 실제 배포 환경에 가까운 부하 테스트 가능
- 동시 사용자 수, 반복 횟수, 응답 시간, TPS 확인 가능
- GUI로 시나리오 만들기 쉬움
- 단점
- 테스트 스크립트 관리가 번거러움
- 코드 기반 테스트보다 자동화/버전 관리가 불편할 수 있음
- 정합성 검증은 별도로 DB 확인 로직이 필요함
- 장점
- k6
- 장점
- 코드로 테스트 시나리오 관리 가능
- Git으로 버전 관리하기 좋음
- CI에 붙이기 좋음
- 응답 시간, 실패율, 요청 수 같은 성능 지표 확인 가능
- 단점
- JavaScript 문법을 알아야 함
- DB 정합성 검증은 별도 확인이 필요함
- 장점
장점은 거의 유사하지만, GUI보다 코드를 통해 테스트 시나리오를 관리하는 것이 더 편리하다고 생각되어 k6를 사용하기로 했다.
마무리
오랜만에 새로운 프로젝트를 진행하고, 동시성 제어와 부하 테스트는 다뤄보지 못한 영역이라 재미있을 거 같다. 의미있는 시간을 보냈으면 좋겠다.