서론

개인 프로젝트로 진행하고 있는 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를 사용하기로 했다.

마무리

오랜만에 새로운 프로젝트를 진행하고, 동시성 제어와 부하 테스트는 다뤄보지 못한 영역이라 재미있을 거 같다. 의미있는 시간을 보냈으면 좋겠다.