Projects/[Final] Shopping Mall Project

[부하 테스트] 오늘의 성과와 한계

montmer27 2026. 4. 21. 23:18

오늘은 AllInMarket 프로젝트에서 @Async를 도입하고, 부하 테스트로 동기 처리의 한계를 수치로 확인한 작업을 정리한다.


오늘의 작업 요약

@Async 적용, 부하 테스트 인프라 구축, 동기 처리 한계 수치 확인, 이니셜라이저 개선까지 네 가지를 진행했다.


  1. @Async 적용

AsyncConfig.java를 새로 작성해 @EnableAsync를 활성화하고, dashboardExecutor라는 이름의 스레드 풀을 정의했다. core 5, max 10 사이즈로 설정했다.

DashboardService.updateSellerDashboard()에 @Async("dashboardExecutor")를 붙여 대시보드 업데이트를 비동기로 분리했다. 기존에 내부 try-catch로 에러를 격리하는 구조가 이미 있어서 비동기 전환 후에도 에러 흐름은 안전하게 유지된다.


  1. 부하 테스트 인프라 구축

k6 시나리오 파일 scenario-c.js를 작성했다. cart → order → payment 전체 플로우를 한 번에 커버하는 구성이다.

엔드포인트별로 name 태그를 달아 Grafana에서 구분할 수 있게 했고, RUN_TAG 환경변수로 before/after를 구분해 InfluxDB에 저장되는 것까지 확인했다.


  1. 동기 처리의 한계 수치로 확인

@Async 도입 전, 동기 상태에서 50 RPS 부하를 걸었을 때 POST /payments의 평균 응답시간이 12.86초까지 치솟았고 타임아웃이 다수 발생했다. 사실상 시스템이 붕괴하는 상태였다.

이 결과 자체가 @Async 도입 필요성의 근거가 된다. 대시보드 업데이트처럼 결제 응답과 무관한 작업을 메인 스레드에서 함께 처리하면, 트래픽이 몰릴 때 응답 지연이 폭발적으로 늘어난다는 것을 수치로 증명한 셈이다.


  1. 이니셜라이저 개선

createDummySellerDashboard()를 추가해 테스트 시작 전에 seller_dashboard row가 실제로 존재하도록 만들었다. 기존에는 addOrder()의 UPDATE 쿼리가 수정할 행이 없어 현실적인 테스트가 되지 않았던 문제를 해결했다.


남은 과제

비교 가능한 부하 구간을 아직 찾지 못했다. 20 RPS는 부하가 낮아 @Async의 효과보다 커넥션 풀 오버헤드가 커서 오히려 after가 느렸고, 50 RPS는 before(동기)가 타임아웃으로 붕괴해 공정한 비교가 불가능했다. 30~40 RPS 구간에서 재시도가 필요하다.

로컬 환경 노이즈도 변수다. 맥북 단일 머신에서 DB, 앱, k6가 함께 실행되다 보니 약 5ms 수준의 노이즈가 상존한다. before → after 순차 실행 구조라 DB 데이터 누적과 JVM 워밍업 상태도 달라져 결과 오염이 발생한다.

마지막으로 백그라운드 작업의 성공률이 아직 미검증 상태다. @Async 적용 후 updateSellerDashboard가 실제로 정상 완료되는지는 애플리케이션 로그로만 확인 가능하고, k6 메트릭으로는 측정할 수 없다. 별도 검증 방법을 고민해야 한다.