속도 제한¶
Continuum Router는 남용을 방지하고, 리소스를 공정하게 배분하며, 백엔드 서비스를 과부하로부터 보호하기 위해 요청 속도를 제한합니다. 속도 제한 시스템은 다중 계층 보호와 함께 토큰 버킷 알고리즘을 사용합니다.
개요¶
라우터는 다중 계층 속도 제한을 구현합니다:
- 클라이언트별 제한: 개별 클라이언트가 시스템을 압도하는 것을 방지
- 백엔드별 제한: 개별 백엔드 서비스를 과부하로부터 보호
- API 키별 제한: 인증된 키 단위로 제한을 적용하고, 키별 오버라이드 지원
- 모델별 제한: 특정 (고비용) 모델 보호
- 전역 제한: 전체 시스템 안정성 보장
설정¶
기본 설정¶
rate_limiting:
enabled: true
storage: memory # 분산 설정의 경우 "redis"
limits:
per_client:
requests_per_second: 10
burst_capacity: 20
per_backend:
requests_per_second: 100
burst_capacity: 200
global:
requests_per_second: 1000
burst_capacity: 2000
API 키별 속도 제한¶
API 키에는 두 가지 메커니즘이 적용됩니다.
-
rate_limiting.limits안의per_api_key차원: 키로 인증된 모든 클라이언트에 토큰 버킷 제한을 적용합니다. -
api_keys섹션의 개별 키에 거는rate_limit오버라이드 (분당 요청 수):
우회 설정¶
특정 클라이언트는 속도 제한을 완전히 우회할 수 있습니다:
rate_limiting:
# 속도 제한을 우회하는 화이트리스트 IP
whitelist:
- "192.168.1.0/24"
- "10.0.0.1"
# 속도 제한을 우회하는 API 키
bypass_keys:
- "admin-key-123"
- "monitoring-key-456"
클라이언트 식별¶
라우터는 다음 우선순위로 클라이언트를 식별합니다:
- API 키 -
Authorization: Bearer <token>또는x-api-key헤더 (선호) -
다른 IP에서도 정확한 추적 제공
-
X-Forwarded-For 헤더 (프록시/로드 밸런서 시나리오)
- 신뢰할 수 있는 프록시에서 온 요청에만 적용
-
use_rightmost_xff: true(기본값)이면 체인의 가장 오른쪽 IP를 사용하므로 위조가 어려움 -
X-Real-IP 헤더 (대체 프록시 헤더)
-
마찬가지로 신뢰할 수 있는 프록시에서 온 경우에만 적용
-
직접 IP 주소 (프록시 헤더가 없는 경우)
- 요청이 라우터에 직접 도달할 때 사용
신뢰 프록시 설정¶
rate_limiting:
# X-Forwarded-For / X-Real-IP 헤더 설정이 허용되는 프록시
trusted_proxies:
- "10.0.0.0/8"
- "192.168.1.1"
# X-Forwarded-For 체인에서 가장 오른쪽 IP 사용 (기본값: true)
use_rightmost_xff: true
신뢰 목록에 없는 출처가 보낸 포워딩 헤더는 무시되므로, 클라이언트가 X-Forwarded-For를 위조해 클라이언트별 제한을 회피할 수 없습니다.
속도 제한 전략¶
토큰 버킷 알고리즘¶
라우터는 장기 속도 제한을 유지하면서 버스트 트래픽을 허용하는 토큰 버킷 알고리즘을 사용합니다:
- 버킷 용량: 최대 토큰 수 (burst_capacity)
- 리필 속도: 초당 추가되는 토큰 (requests_per_second)
- 토큰 비용: 각 요청은 하나의 토큰을 소비
작동 방식¶
- 각 클라이언트는 토큰이 가득 찬 버킷으로 시작
- 각 요청마다 토큰이 소비됨
- 토큰은 일정한 속도로 리필됨
- 버킷이 비면 요청이 거부됨
모델별 제한¶
클라이언트별, 백엔드별, API 키별, 전역 차원에 더해 개별 모델을 대상으로 제한을 걸 수 있습니다. 저렴한 모델은 그대로 두고 고비용 모델만 보호할 때 유용합니다:
rate_limiting:
limits:
per_model:
gpt-4:
requests_per_second: 2
burst_capacity: 5
gpt-3.5-turbo:
requests_per_second: 20
burst_capacity: 50
응답 헤더¶
성공 응답¶
요청이 속도 제한 내에 있을 때:
속도 제한 초과 응답¶
속도 제한이 초과되었을 때:
HTTP/1.1 429 Too Many Requests
Retry-After: 30
Content-Type: application/json
{
"error": {
"message": "속도 제한 초과: 5초당 20개 요청의 버스트 제한 초과",
"type": "rate_limit_error",
"code": "rate_limit_exceeded"
}
}
모니터링¶
메트릭¶
속도 제한 동작은 Prometheus 메트릭에서 추적됩니다:
# 수행된 총 속도 제한 검사 수
rate_limit_checks_total 10342
# 거부된 요청 (제한 차원별 레이블)
rate_limit_exceeded_total{limit_type="per_client"} 42
# 현재 토큰 버킷 잔량과 용량
rate_limit_tokens_remaining{bucket_type="per_client",identifier="..."} 15
rate_limit_bucket_capacity{bucket_type="per_client"} 20
# 화이트리스트 및 우회(API 키) 요청
rate_limit_whitelisted_requests_total 123
rate_limit_bypassed_requests_total 45
로깅¶
속도 제한 이벤트는 컨텍스트와 함께 로깅됩니다:
{
"level": "warn",
"msg": "속도 제한 초과",
"client_id": "abc123...",
"endpoint": "/v1/chat/completions",
"limit_type": "burst",
"limit_value": 20,
"window": "5s"
}
우회 메커니즘¶
IP 화이트리스트¶
신뢰할 수 있는 IP 주소나 CIDR 범위를 화이트리스트에 추가:
rate_limiting:
whitelist:
- "192.168.1.0/24" # 내부 네트워크
- "10.0.0.1" # 관리자 서버
- "172.16.0.0/16" # 회사 네트워크
API 키 우회¶
특정 API 키는 모든 속도 제한을 우회할 수 있습니다:
헬스 체크 면제¶
헬스 체크와 메트릭 엔드포인트는 속도 제한에서 자동으로 면제됩니다:
/health/healthz/metrics
스토리지 백엔드¶
메모리 스토리지 (기본)¶
인메모리 스토리지는 빠르지만 인스턴스 간 공유되지 않습니다:
장점:
- 외부 의존성 없음
- 낮은 지연 시간
- 간단한 설정
단점:
- 라우터 인스턴스 간 공유되지 않음
- 재시작 시 손실
- 단일 인스턴스 배포에만 적합
Redis 스토리지 (분산)¶
Redis 스토리지는 여러 라우터 인스턴스 간 분산 속도 제한을 가능하게 합니다:
rate_limiting:
storage: redis
redis:
url: "redis://localhost:6379"
key_prefix: "continuum:ratelimit:" # 속도 제한 키 접두사 (기본값)
ttl: 3600 # 속도 제한 키 TTL (초)
자격 증명은 URL에 포함할 수 있고 (redis://:password@host:6379), ${REDIS_PASSWORD} 같은 환경변수 치환도 사용할 수 있습니다.
장점:
- 모든 라우터 인스턴스 간 공유
- 재시작 시에도 유지
- 정확한 전역 제한
단점:
- Redis 인프라 필요
- 약간 더 높은 지연 시간
- 추가적인 운영 복잡성
핫 리로드 지원¶
속도 제한 설정은 즉시 업데이트를 위한 핫 리로드를 지원합니다:
# 이 설정들은 재시작 없이 즉시 업데이트됩니다
rate_limiting:
enabled: true # ✅ 즉시: 속도 제한 활성화/비활성화
limits:
per_client:
requests_per_second: 10 # ✅ 즉시: 새 제한이 즉시 적용
burst_capacity: 20 # ✅ 즉시: 버스트 설정이 즉시 업데이트
per_backend:
requests_per_second: 100 # ✅ 즉시: 백엔드 제한이 즉시 업데이트
모범 사례¶
1. 보수적으로 시작¶
실제 사용에 따라 더 엄격한 제한으로 시작하고 완화하세요:
2. 모니터링 및 조정¶
메트릭을 사용하여 실제 트래픽 패턴을 이해하세요:
rate_limit_exceeded_total메트릭 추적- 합법적인 트래픽 vs 남용 트래픽 식별
- 데이터에 기반하여 제한 조정
3. 다른 계층 사용¶
키별 오버라이드(분당 요청 수)로 사용자 클래스마다 계층화된 속도 제한을 구현하세요:
api_keys:
api_keys:
- key: "free-tier-key"
rate_limit: 60
- key: "pro-tier-key"
rate_limit: 600
- key: "enterprise-tier-key"
rate_limit: 6000
4. 고비용 모델 보호¶
비용이 많이 드는 모델에는 per_model 제한으로 더 엄격한 제한을 적용하세요:
5. 프로덕션에서는 Redis 사용¶
다중 인스턴스 배포의 경우 Redis 사용:
문제 해결¶
일반적인 문제¶
속도 제한이 적용되지 않음¶
증상: 클라이언트가 설정된 제한을 초과할 수 있음
해결책: 1. 클라이언트가 화이트리스트에 있는지 확인 2. rate_limiting.enabled가 true인지 확인 3. 속도 제한 초기화에 대한 로그 확인 4. API 키 형식이 올바른지 확인
너무 많은 오탐지¶
증상: 합법적인 트래픽이 속도 제한됨
해결책: 1. 버스트 트래픽에 대해 burst_capacity 증가 2. 클라이언트 식별 검토 (여러 클라이언트가 그룹화될 수 있음) 3. API 키별 제한 사용 고려 4. 합법적인 IP를 화이트리스트에 추가
Redis 연결 문제¶
증상: Redis 스토리지에서 속도 제한이 작동하지 않음
해결책: 1. Redis 연결 확인 2. Redis 인증 확인 3. 연결 풀 설정 검토 4. Redis 성능 모니터링
디버그 로깅¶
디버그 로깅을 켜면 속도 제한 판정 과정을 로그에서 볼 수 있습니다:
관련 문서¶
- 속도 제한 아키텍처 - 구현 세부 사항 및 설계 결정
- 설정 가이드 - 전체 설정 참조
- 관리자 API - 런타임 설정 관리
- 메트릭 - 모니터링 및 관측성
- 오류 처리 - 오류 코드 및 재시도 전략