이 저장소는 세션 기반 인증 서버(auth-session), JWT 기반 인증 서버(auth-jwt), 상품 재고 서버(product), 주문 서버(order)를 분리하여 구성한 마이크로서비스 실험 환경입니다. Locust 기반 부하 테스트(loadtest)를 통해 세션 인증 서버에 DDoS 성격의 트래픽이 가해졌을 때 주문 서비스가 어떤 병목을 겪는지 관찰하고, 구조 개선 방법을 검증하는 것이 핵심 목표입니다.
[client/locust]
├─ POST /auth/login (session) ───────▶ [auth-session]
│ │ JSESSIONID 쿠키 │
│ └─────────────────────────────┘
├─ POST /auth/login (JWT) ───────────▶ [auth-jwt]
│ │ Bearer token │
│ └─────────────────────────────┘
└─ POST /order ──────────────────────▶ [order]
│ 1) JWT 검증 → auth-jwt
│ 2) 세션 검증 → auth-session /auth/whoami
└─ 상품 예약 요청 ─────────▶ [product]
RestTemplate 빈을 직접 OrderApplication에서 생성하던 초기 구조에서는 AuthInterceptor가 RestTemplate을 주입받는 과정에서 OrderApplication과의 순환 참조가 발생해 애플리케이션이 부팅되지 않았습니다.
RestTemplate빈을 별도의HttpClientConfig에서 생성하고,WebConfig는 순수하게 인터셉터 등록만 담당하도록 분리했습니다.- 이로써
OrderApplication은 순수한 부트스트랩 클래스가 되었고, 인터셉터-빈 간 의존성 순환이 해소되었습니다.
| Type | Name | # Requests | # Fails | Median | p95 | p99 | Avg | Min | Max | Avg size | Current RPS | Current Fail/s |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| POST | auth-jwt: /auth/login | 419 | 0 | 1502ms | 1600ms | 1900ms | 1529ms | 1503 | 2005 | 241B | 10.5 | 0 |
| POST | auth-session: /auth/login | 339 | 0 | 6300ms | 7300ms | 7500ms | 5489ms | 1507 | 7714 | 68B | 6.6 | 0 |
| POST | order (JWT) | 320 | 0 | 7ms | 16ms | 24ms | 8.17ms | 5 | 84 | 102B | 5.9 | 0 |
| POST | order (SESSION cookie) | 313 | 241 | 5000ms | 5000ms | 5000ms | 4505ms | 1512 | 5018 | 23B | 5.9 | 5.9 |
| Aggregated | 1391 | 241 | 1500ms | 6900ms | 7300ms | 2814ms | 5 | 7714 | 118B | 28.9 | 5.9 |
결론
- 세션 로그인 경로는 5초 이상 응답이 지연되며, 동일한 세션 쿠키로 주문을 시도하면 241건이 실패했습니다. 이는 세션 인증 서버의 처리 지연이 주문 서비스까지 전파된 결과입니다.
- JWT 로그인과 JWT 기반 주문은 평균 8ms 수준으로 안정적인 응답을 유지하여, 토큰 기반 경로가 세션 기반 병목을 우회한다는 점을 보여줍니다.
- 따라서 주문 서비스가 두 인증 경로를 모두 지원하더라도, 지연이 큰 세션 서버에 대한 동기 호출은 전체 요청의 17% 수준(241/1391)을 실패시키는 병목 지점이 됩니다.
각 서비스는 독립적인 Spring Boot 애플리케이션입니다. JDK 17과 Gradle이 설치되어 있다면, 루트 디렉터리에서 각각 실행할 수 있습니다.
# auth-session (8081)
cd auth-session
./gradlew bootRun
# auth-jwt (8082)
cd auth-jwt
./gradlew bootRun
# product (8083)
cd product
./gradlew bootRun
# order (8084)
cd order
./gradlew bootRunauth-session과auth-jwt는demo.delay.ms속성으로 전역 지연을 주입할 수 있어, 의도적으로 병목을 재현하는 데 활용할 수 있습니다.
cd loadtest
locust -f locustfile.py --host=http://dummy
- 기본 값으로는
AUTH_SESSION_BASE=http://localhost:8081,AUTH_JWT_BASE=http://localhost:8082,ORDER_BASE=http://localhost:8084,PRODUCT_BASE=http://localhost:8083에 트래픽을 분산합니다. - 단일 사용자 클래스(
SingleUser)가 세션/토큰 로그인 폭격과 주문 요청을 동시에 수행하도록 구성되어 있으며, 가중치를 통해 세션 공격과 주문 시나리오의 비율을 제어합니다.
| 서비스 | 엔드포인트 | 설명 |
|---|---|---|
| auth-session | POST /auth/login |
세션 로그인, JSESSIONID 쿠키 발급 |
| auth-session | GET /auth/whoami |
세션 쿠키 검증, 사용자 정보 반환 |
| auth-jwt | POST /auth/login |
JWT 발급 |
| auth-jwt | GET /auth/whoami |
토큰 검증 및 사용자 정보 조회 |
| product | POST /product/{id}/reserve |
재고 차감 및 잔여 재고 반환 |
| order | POST /order |
인증 검증 후 주문 생성, 재고 예약 위임 |
| order | GET /order/{id} |
주문 조회 |