트래픽 급증 대비 아키텍처 패턴 (Rate Limit · Circuit Breaker · Bulkhead)
서비스는 항상 일정한 트래픽을 받지 않는다.
이벤트, 광고, 점검 알림, 외부 봇 접근 등으로 인해 순간적인 트래픽 급증이 발생할 수 있다.
이때 API와 서버가 이를 제대로 처리하지 못하면 장애로 직결된다.
본 글에서는 고트래픽 상황에서 시스템을 보호하기 위한 아키텍처 패턴들을 정리한다.
#Rate Limiting
Rate Limiting은 “특정 사용자 또는 IP가 너무 많은 요청을 보내지 못하도록 제한하는 기술”이다.
봇 공격, 반복 재시도, 과도한 호출로 인한 장애를 예방하는 데 효과적이다.
적용 방식
- IP 또는 사용자 단위 요청 제한
- 특정 API별 제한 (예: 로그인, 회원가입)
- 외부 API 호출 제한
Redis 기반 Rate Limit 예시
INCR user:{id}:count
EXPIRE user:{id}:count 60
이렇게 하면 1분 안에 일정 횟수를 넘으면 차단할 수 있다.
Spring Cloud Gateway 또는 NGINX에서도 쉽게 설정이 가능하다.
주요 알고리즘
- Fixed Window
- Sliding Window
- Token Bucket (가장 일반적)
- Leaky Bucket
#Circuit Breaker
Circuit Breaker는 외부 API 또는 내부 서비스가 장애 상태일 때, 추가 호출을 차단하여 전체 시스템 장애로 확산되는 것을 방지한다.
Netflix Hystrix 이후 현재는 Resilience4j가 표준이다.
동작 원리
- Closed: 정상 상태, 요청 통과
- Open: 장애 감지 → 모든 요청 차단
- Half-Open: 일부 요청만 테스트
Resilience4j 예시
CircuitBreakerConfig config = CircuitBreakerConfig.custom()
.failureRateThreshold(50)
.waitDurationInOpenState(Duration.ofSeconds(5))
.build();
Circuit Breaker는 장애 확산 방지에 매우 효과적이며
외부 API, 결제 시스템, 인증 서버 연동 시 필수적이다.
#Bulkhead
Bulkhead 패턴은 시스템의 리소스를 “격리”하여, 특정 기능에서 장애가 발생해도 전체 서비스에 영향을 주지 않도록 한다.
선박의 격벽 구조에서 유래한 개념이다.
왜 필요한가?
- 특정 API가 느려지면 전체 스레드가 고갈될 수 있음
- 외부 API 지연이 서비스 전체를 마비시킴
- 장시간 대기 요청이 스레드 풀을 점유
격리 전략
- API마다 별도 스레드 풀 구성
- 서비스 기능을 독립 실행 환경으로 분리
- DB 연결 풀 분리
예시: CPU·IO 작업 분리
CPU 작업은 CPU Pool, IO 작업은 IO Pool로 분리한다.
ExecutorService cpuPool = Executors.newFixedThreadPool(8);
ExecutorService ioPool = Executors.newCachedThreadPool();
Spring WebFlux나 WebClient 사용 시 Bulkhead는 더욱 중요한 안정성 기법이 된다.
#Fallback 전략
Fallback은 Circuit Breaker와 함께 사용되는 보조 전략이다.
장애 발생 시 대체 데이터 또는 기본 응답을 제공해 사용자 경험을 보호한다.
- 외부 API 실패 → 캐시 데이터 반환
- 일부 기능 → “잠시 후 다시 시도해주세요” 기본 메시지
- 랭킹/리뷰 서비스 → TTL 지난 이전 데이터라도 제공
Resilience4j Fallback 예시
@CircuitBreaker(name = "external", fallbackMethod = "fallback")
public Response callApi() {
return externalApi.call();
}
public Response fallback(Throwable t) {
return new Response("temporary data");
}
#실제 서비스에서의 적용 예시
로그인/인증
- IP 단위 Rate Limit
- OTP·SMS 전송 제한
랭킹/피드 API
- TTL 캐싱
- CDN 캐싱
- Bulkhead로 격리
외부 결제/인증 API
- Circuit Breaker 필수
- Fallback 데이터 제공
대량 조회 서비스
- Redis Rate Limit
- Bulkhead로 스레드 풀 격리
마치며
트래픽 급증은 언제든 발생할 수 있으며, 이를 제대로 대비하지 않으면 전체 서비스 장애로 이어진다.
Rate Limit, Circuit Breaker, Bulkhead는 서로 보완적으로 작동하며, 시스템의 안정성과 탄력성을 크게 높인다.
다음 글에서는 WebClient 기반 비동기 처리 최적화를 다룬다.
Virtual Thread와 비교했을 때 WebClient가 어떤 상황에서 적합한지도 함께 설명할 예정이다.
'TIL' 카테고리의 다른 글
| 11/5 (0) | 2025.11.05 |
|---|---|
| 11/4 (0) | 2025.11.04 |
| Spring Boot 성능 최적화 6 (0) | 2025.10.31 |
| Spring Boot 성능 최적화 5 (0) | 2025.10.30 |
| Spring Boot 성능 최적화 4 (0) | 2025.10.29 |