💻 프로젝트/트러블 슈팅

[QRoad]운영 전 API 부하 테스트를 진행하며 403을 마주하다 (문제 추적 과정 정리)

SoloQuest 2026. 3. 2. 22:54

1. 배경

지역신문 QR 유입을 대비하여 운영 전 API 안정성을 점검하고자 부하 테스트를 진행했다.

  • 프론트엔드: Vercel
  • 백엔드: EC2 + Nginx
  • 테스트 도구: k6
  • 테스트 대상 API:
https://api.qroad.info/api/qr/3
 

목표는 다음과 같았다.

  • 동시 사용자 30~50명 시나리오 테스트
  • p95 500ms 이하 유지
  • 에러율 1% 미만 유지

2. 1차 실수: 잘못된 레이어 테스트

처음에는 다음 주소를 테스트했다.

https://www.qroad.info/a/3
 

하지만 curl 응답을 확인해보니:

Server: Vercel
 

즉, 프론트엔드 정적 페이지를 테스트한 것이었다.
DB 조회 API가 아닌 레이어를 테스트하고 있었던 것이다.

→ 테스트 대상을 api.qroad.info로 수정.


3. 실제 API 테스트 결과

k6로 /api/qr/3를 호출하자 결과는 다음과 같았다.

http_req_failed: 100%
status is 200: 실패
 

모든 요청이 실패로 집계되었다.

하지만 응답 시간은 매우 짧았다.

avg: 3~5ms
 

이는 성능 문제가 아니라 즉시 거부 응답임을 의미한다.


4. 원인 추적 과정

(1) 보안그룹 확인

  • 443 포트 전체 허용 상태
  • 네트워크 차단 아님

(2) nginx 설정 확인

sudo grep -R "deny" /etc/nginx
 

결과: 실제 deny 설정 없음

→ nginx 레벨 차단 아님

(3) curl 테스트

curl -i https://api.qroad.info/api/qr/3
 

결과:

HTTP/1.1 403
 

Origin, Referer 헤더를 추가해도 동일하게 403.


5. 현재 추정 원인

  • 애플리케이션 레벨(Spring Security 등)에서 접근 차단
  • 세션 또는 쿠키 기반 접근 허용 구조
  • 브라우저 정상 흐름에서만 접근 가능하도록 설계

즉, 서버 성능 문제 이전에
API 접근 정책 설계 문제를 먼저 정리해야 하는 상태였다.


6. 배운 점

1) 부하 테스트는 단순히 트래픽을 때리는 작업이 아니다

레이어를 정확히 이해하지 못하면
엉뚱한 부분을 테스트하게 된다.

2) 403도 의미 있는 결과다

  • 네트워크 차단인지
  • nginx 레벨인지
  • 애플리케이션 레벨인지

단계적으로 좁혀가는 과정 자체가 트러블슈팅이다.

3) 운영 전 점검의 가치

실제 운영 전에:

  • API 접근 정책 문제 발견
  • 인증/보안 설계 재검토 필요성 인지

이 자체가 리스크 관리 경험이다.


7. 다음 단계

  • Spring Security 설정 점검
  • /api/qr/** 접근 정책 명확화
  • 인증 전략 정리 후 재테스트 진행

마무리

이번 부하 테스트는 성능 검증 이전에
“API 접근 구조를 재점검하는 과정”이 되었다.

단순한 부하 테스트 실행이 아니라,
문제 정의 → 가설 수립 → 원인 축소 → 구조 분석의 흐름을 경험한 사례였다.

운영 전 점검은
장애 발생 이후 대응보다 훨씬 가치 있는 작업임을 체감한 순간이었다.