콘텐츠로 이동

속도 제한

Continuum Router는 남용을 방지하고, 공정한 리소스 할당을 보장하며, 백엔드 서비스를 과부하로부터 보호하기 위한 고급 속도 제한 기능을 제공합니다. 속도 제한 시스템은 다중 계층 보호와 함께 토큰 버킷 알고리즘을 사용합니다.

개요

라우터는 다중 계층 속도 제한을 구현합니다:

  • 클라이언트별 제한: 개별 클라이언트가 시스템을 압도하는 것을 방지
  • 백엔드별 제한: 개별 백엔드 서비스를 과부하로부터 보호
  • 전역 제한: 전체 시스템 안정성 보장
  • 엔드포인트별 제한: 중요한 엔드포인트에 대한 특별 처리

설정

기본 설정

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 키에 대한 사용자 정의 속도 제한을 설정할 수 있습니다:

api_keys:
    - key: "premium-user-key"
    name: "프리미엄 사용자"
    rate_limit:
      requests_per_second: 100
      burst_capacity: 200

    - key: "standard-user-key"
    name: "표준 사용자"
    rate_limit:
      requests_per_second: 10
      burst_capacity: 20

우회 설정

특정 클라이언트는 속도 제한을 완전히 우회할 수 있습니다:

rate_limiting:
  # 속도 제한을 우회하는 화이트리스트 IP
  whitelist:
        - "192.168.1.0/24"
        - "10.0.0.1"

  # 속도 제한을 우회하는 API 키
  bypass_keys:
        - "admin-key-123"
        - "monitoring-key-456"

클라이언트 식별

라우터는 다음 우선순위로 클라이언트를 식별합니다:

  1. API 키 - Authorization: Bearer <token> 헤더 (선호)
  2. 처음 16자가 클라이언트 식별자로 사용됨
  3. 다른 IP에서도 정확한 추적 제공

  4. X-Forwarded-For 헤더 (프록시/로드 밸런서 시나리오)

  5. 프록시 헤더에서 실제 클라이언트 IP 추출

  6. X-Real-IP 헤더 (대체 프록시 헤더)

  7. 다른 프록시 설정에 대한 폴백

  8. 직접 IP 주소 (프록시 헤더가 없는 경우)

  9. 요청이 라우터에 직접 도달할 때 사용

클라이언트 식별 예제

# 클라이언트 식별 설정
rate_limiting:
  client_identification:
    priority:
      - api_key                   # Bearer 토큰 (처음 16자가 ID로 사용)
      - x_forwarded_for           # 프록시/로드 밸런서 헤더
      - x_real_ip                 # 대체 IP 헤더
    fallback: "unknown"           # 식별자가 없을 때

속도 제한 전략

토큰 버킷 알고리즘

라우터는 장기 속도 제한을 유지하면서 버스트 트래픽을 허용하는 토큰 버킷 알고리즘을 사용합니다:

  • 버킷 용량: 최대 토큰 수 (burst_capacity)
  • 리필 속도: 초당 추가되는 토큰 (requestspersecond)
  • 토큰 비용: 각 요청은 하나의 토큰을 소비

작동 방식

  1. 각 클라이언트는 토큰이 가득 찬 버킷으로 시작
  2. 각 요청마다 토큰이 소비됨
  3. 토큰은 일정한 속도로 리필됨
  4. 버킷이 비면 요청이 거부됨

이중 윈도우 방식

/v1/models와 같은 중요한 엔드포인트의 경우 라우터는 이중 윈도우 방식을 사용합니다:

  • 지속 제한: 시간 경과에 따른 과도한 사용 방지 (100 req/min)
  • 버스트 보호: 빠른 연속 요청 포착 (20 req/5s)
# 예제: /v1/models 엔드포인트 속도 제한
rate_limiting:
  models_endpoint:
    sustained_limit: 100          # 분당 최대 요청 수
    burst_limit: 20               # 5초 윈도우 내 최대 요청 수
    window_duration: 60s          # 지속 제한을 위한 슬라이딩 윈도우
    burst_window: 5s              # 버스트 감지 윈도우

응답 헤더

성공 응답

요청이 속도 제한 내에 있을 때:

HTTP/1.1 200 OK
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640995200

속도 제한 초과 응답

속도 제한이 초과되었을 때:

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_violations_total{client_id="abc123...",endpoint="/v1/chat/completions"} 42

# 현재 토큰 버킷 수준
rate_limit_tokens_available{client_id="abc123...",tier="per_client"} 15

# 속도 제한 우회 이벤트
rate_limit_bypassed_total{reason="whitelisted_ip"} 123

로깅

속도 제한 이벤트는 컨텍스트와 함께 로깅됩니다:

{
  "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 키는 모든 속도 제한을 우회할 수 있습니다:

rate_limiting:
  bypass_keys:
        - "admin-key-123"
        - "monitoring-key-456"
        - "load-test-key-789"

헬스 체크 면제

헬스 체크 엔드포인트는 속도 제한에서 자동으로 면제됩니다:

  • /health
  • /health/ready
  • /health/live
  • /metrics

스토리지 백엔드

메모리 스토리지 (기본)

인메모리 스토리지는 빠르지만 인스턴스 간 공유되지 않습니다:

rate_limiting:
  storage: memory

장점:

  • 외부 의존성 없음
  • 낮은 지연 시간
  • 간단한 설정

단점:

  • 라우터 인스턴스 간 공유되지 않음
  • 재시작 시 손실
  • 단일 인스턴스 배포에만 적합

Redis 스토리지 (분산)

Redis 스토리지는 여러 라우터 인스턴스 간 분산 속도 제한을 가능하게 합니다:

rate_limiting:
  storage: redis
  redis:
    url: "redis://localhost:6379"
    db: 0
    password: "${REDIS_PASSWORD}"
    pool_size: 10

장점:

  • 모든 라우터 인스턴스 간 공유
  • 재시작 시에도 유지
  • 정확한 전역 제한

단점:

  • Redis 인프라 필요
  • 약간 더 높은 지연 시간
  • 추가적인 운영 복잡성

핫 리로드 지원

속도 제한 설정은 즉시 업데이트를 위한 핫 리로드를 지원합니다:

# 이 설정들은 재시작 없이 즉시 업데이트됩니다
rate_limiting:
  enabled: true                  # ✅ 즉시: 속도 제한 활성화/비활성화
  limits:
    per_client:
      requests_per_second: 10    # ✅ 즉시: 새 제한이 즉시 적용
      burst_capacity: 20         # ✅ 즉시: 버스트 설정이 즉시 업데이트
    per_backend:
      requests_per_second: 100   # ✅ 즉시: 백엔드 제한이 즉시 업데이트

모범 사례

1. 보수적으로 시작

실제 사용에 따라 더 엄격한 제한으로 시작하고 완화하세요:

rate_limiting:
  limits:
    per_client:
      requests_per_second: 5      # 낮게 시작
      burst_capacity: 10

2. 모니터링 및 조정

메트릭을 사용하여 실제 트래픽 패턴을 이해하세요:

  • rate_limit_violations_total 메트릭 추적
  • 합법적인 트래픽 vs 남용 트래픽 식별
  • 데이터에 기반하여 제한 조정

3. 다른 계층 사용

다른 사용자 클래스에 대해 계층화된 속도 제한 구현:

api_keys:
    - key: "free-tier-key"
    rate_limit:
      requests_per_second: 1
      burst_capacity: 5

    - key: "pro-tier-key"
    rate_limit:
      requests_per_second: 10
      burst_capacity: 20

    - key: "enterprise-tier-key"
    rate_limit:
      requests_per_second: 100
      burst_capacity: 200

4. 중요한 엔드포인트 보호

비용이 많이 드는 작업에 더 엄격한 제한 적용:

rate_limiting:
  endpoint_overrides:
    "/v1/chat/completions":
      per_client:
        requests_per_second: 5    # 비용이 많이 드는 엔드포인트에 더 엄격
    "/v1/models":
      per_client:
        requests_per_second: 10   # 저렴한 엔드포인트에 더 관대

5. 프로덕션에서는 Redis 사용

다중 인스턴스 배포의 경우 Redis 사용:

rate_limiting:
  storage: redis
  redis:
    url: "redis://redis-cluster:6379"
    pool_size: 20
    connect_timeout: 5s

문제 해결

일반적인 문제

속도 제한이 적용되지 않음

증상: 클라이언트가 설정된 제한을 초과할 수 있음

해결책: 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 성능 모니터링

디버그 로깅

속도 제한에 대한 디버그 로깅 활성화:

logging:
  level: debug
  modules:
    rate_limiting: debug

향후 개선 사항

속도 제한 시스템의 계획된 개선 사항:

  • 엔드포인트별 설정: 각 API 엔드포인트에 대한 사용자 정의 제한
  • 동적 속도 조정: 백엔드 용량에 기반한 자동 스케일링
  • 분산 조정: 다중 리전 배포를 위한 더 나은 Redis 통합
  • 비용 기반 제한: 다른 작업에 대한 다른 토큰 비용
  • 쿼터 관리: 속도 제한 외에 월간/일간 쿼터 제한
  • 고급 분석: 속도 제한 모니터링을 위한 실시간 대시보드

관련 문서