4장. 처리율 제한 장치의 설계

1. 처리율 제한 장치

1-1. 의미

  • 클라이언트 또는 서비스가 보내는 트래픽의 처리율을 제어하기 위한 장치
  • 특정 기간 내에 전송되는 클라이언트의 요청 횟수 제한
    • 예시
      • 사용자는 초당 2회 이상의 새 글을 올릴 수 없음
      • 같은 IP 주소로는 하루에 10개 이상의 계정 생성 불가
      • 같은 디바이스로는 주당 5회 이상 리워드 요청 불가

1-2. API에 처리율 제한 장치를 두면 좋은점

  • 악의적 공격에 의한 자원 고갈 방지 가능
    • DoS 공격뿐만 아니라, 무차별 대입 공격(Brute-force attack), 크리덴셜 스터핑(Credential stuffing) 등
    • 비용이 저렴하면서도 시스템에 치명적인 공격을 효과적으로 방어
    • 특정 IP나 계정의 비정상적인 요청 패턴을 초기에 차단 → 시스템 전체를 보호
  • 비용 관리: 예측 가능한 인프라 운영
    • 인프라 자원의 상한선을 설정 → 예측 가능한 비용 내에서 서비스 운영 가능
    • 우선순위가 높은 핵심 API에 더 많은 리소스를 할당 → 전략적 자원 분배 가능
  • 서버 과부하 방지
    • 봇 트래픽/잘못된 사용 패턴을 걸러내어 안정성 확보
    • 선량한 사용자들이 안정적으로 서비스를 이용할 수 있도록 트래픽을 제어 → 서비스의 전반적인 품질과 신뢰도를 높임

2. 프레임 워크

[1단계] 문제 이해 및 설계 범위 확정

[1-1] 면접관과의 소통을 통한 구현 기능 확인

항목질문
처리율 제한 장치 설계의 종류클라이언트 측? 서버 측?
API 호출 제어 기준주소? 사용자 ID? 기타?
시스템 규모스타트업? 대규모?
동작 환경분산 환경 여부
독립된 서비스? 앱 코드 포함?
UX사용자의 요청이 처리율 제한 장치에 의해 걸러진 경우 사용자에게 알림 여부?

[1-2]요구사항

  • 설정된 처리율을 초과하는 요청은 정확하게 제한
  • 낮은 응답 시간
  • 가능한 한 적은 메모리 사용
  • 분산형 처리율 제한(distributed rate limiting)
    • 하나의 처리율 제한 장치를 여러 서버나 프로세스에서 공유할 수 있어야 함
  • 예외 처리
    • 요청이 제한되었을 때는 그 사실을 사용자에게 분명하게 보여주어야 함
  • 높은 결함 감내성(fault tolerance)
    • 제한 장치에 장애가 생기더라도 전체 시스템에 영향을 주어서는 안됨

[2단계] 개략적 설계안 제시 및 동의 구하기

[2-1]처리율 제한 장치 배치 전략

(1) 클라이언트 측: X
  • 요청 위변조 가능성 큼 → 신뢰 불가
  • 모든 클라이언트 구현 통제 불가
(2) 서버 측
  • 마이크로서비스 환경에서는 API Gateway가 압도적으로 유리
  • 레거시 모놀리식에서는 미들웨어가 현실적 선택
구분API 게이트웨이미들웨어
적용 환경마이크로서비스 아키텍처레거시 모놀리식 아키텍처
특징현대적인 접근법, 완전 위탁 관리형 서비스(fully managed) 가능 (AWS API Gateway, NGINX, Kong 등)웹 프레임워크 내에 직접 구현
지원 기능인증, 로깅, 라우팅, SSL 종료, IP 관리, 처리율 제한 등 종합 기능 내장단순 처리율 제한 + 비즈니스 로직 연동
정책 관리중앙화된 정책 관리 / 비즈니스 로직과 분리서비스별 개별 구현, 정책 변경 시 코드 배포 필요
운영 측면다중 서비스 지원, 운영팀이 실시간 제어 가능각 서비스 코드 내 변경 필요, 배포 주기와 강하게 연동
장점통합 관리, 확장성, 운영 효율성세밀한 로직 연동, 외부 게이트웨이 불필요
단점초기 도입/구축 복잡성, 게이트웨이에 대한 의존성중복 구현, 유지보수 비용 증가, 확장성 한계

[2-2]처리율 제한 알고리즘

  • 토큰 버킷(token bucket)
  • 누출 버킷(leaky bucket)
  • 고정 윈도 카운터(fixed window counter)
  • 이동 윈도 로그(sliding window log)
  • 이동 윈도 카운터(sliding window counter)

[2-3]개략적인 아키텍처

  • 카운터 단위: 사용자 / IP 주소 / API 엔드포인트
  • 보관 장소: DB는 느림 → 메모리 캐시(Redis)가 적합
    • INCREXPIRE로 원자적 증가 및 TTL 관리
    • Lua 스크립트 활용 시 읽기-쓰기-만료를 한 번에 처리 → 경쟁 조건 방지
    • TTL 만료 후 자동 삭제 → 메모리 관리 용이

[3단계] 상세 설계

[3-1]처리율 제한 규칙 (Rate Limiting Rules)

  • 제한 단위: 사용자 ID, IP 주소, API Key, 엔드포인트, 디바이스 등
  • 시간 윈도우: 초당, 분당, 시간당, 하루 단위 등
  • 엔드포인트별 차등 제한:
    • 핵심 API → 높은 한도
    • 비용 큰 API → 낮은 한도
  • 가중치 기반 제한:
    • 예: 단순 조회 = 1 요청, 복잡한 리포트 생성 = 10 요청

[3-2]한도 초과 트래픽 처리 (Over-limit Traffic Handling)

  • HTTP 상태 코드 429 (Too Many Requests) 반환
  • 헤더 노출:
    • X-RateLimit-Limit (총 한도)
    • X-RateLimit-Remaining (남은 요청 수)
    • X-RateLimit-Reset (초기화 시각)
    • Retry-After (재시도까지 대기 시간)
  • Graceful Fallback:
    • 일부 기능 제한 (쓰기 차단, 읽기만 허용)
    • 캐시/대체 데이터 반환
  • 큐잉 옵션 (Soft limit): 초과 요청을 버리지 않고 대기열에 넣어 순차 처리

[3-3]분산 환경에서의 처리율 제한 구현

(1) 경쟁 조건 (Race Condition)
  • 여러 인스턴스가 동시에 같은 키 갱신 시 발생 가능
  • 해결책
    • Redis INCR + EXPIRE 조합 (원자적 연산)
    • 복잡한 로직 → Lua 스크립트로 원자성 보장
(2) 동기화
  • Sticky Session: 동일 사용자가 항상 같은 서버로 → 단순하지만 확장성 제한
  • 중앙 집중 저장소 (Redis, DynamoDB 등): 모든 인스턴스가 공유 → 분산 환경에 적합
  • 최종 일관성(Eventual Consistency) 모델 허용 여부를 서비스 특성에 맞게 결정
(3) 성능 최적화
  • 에지 서버에서 제한 적용 → 사용자와 가까운 곳에서 차단
  • 로컬 캐시 버퍼링: 초단위 카운트는 로컬에서 관리, 일정 주기마다 Redis와 동기화

[3-4]모니터링 방안

  • 모니터링을 통해 알고리즘의 효과성과 처리율 제한 규칙의 효과성 확인 가능
(1) 모니터링 지표
  • 요청 처리율 (RPS)
  • 거부율 (429 응답 비율)
  • 응답 시간 (레이트 리미터 처리 지연 포함)
  • 활성 키 수 (현재 추적 중인 유저/IP/토큰 개수)
  • 시스템 리소스 (Redis CPU, 메모리, 연결 상태)
  • 에러율 (Redis 장애, 타임아웃 등)
(2) 대시보드 예시
  • API별 요청량/거부율 시각화
  • 슬라이딩 윈도우별 평균 처리율 표시
  • Redis 노드 상태/레플리카 동기화 상태
(3) 알림/자동화
  • SLA 기준 초과 시 알람 발송
  • 장애 발생 시 자동 롤백 / 오토스케일링 트리거

[4단계] 마무리

[4-1] 추가적으로 언급할 부분

(1) 정책 유형
  • 경성 또는 연성 처리율 제한
    • 경성(Hard): 절대적인 임계치 제한
    • 연성(Soft): 초과 요청은 큐에 대기 또는 일부 기능만 제한
      • 예: 읽기는 되지만 쓰기는 차단
(2) 보안/안정성
  • 계층형 방어 (Defense in Depth)

    • L4 (네트워크): iptables/firewall
    • L7 (게이트웨이): 전역 처리율 제한
    • 서비스: 비즈니스 로직별 제어
    • 리소스: DB connection pool, thread pool
  • 동적 임계값 조정

    • 트래픽 상황에 따라 한도를 자동 상향/하향 조정 → 예측 불가한 스파이크 완화
(3) 사용자 경험 최적화
  • 응답 헤더 제공 (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset)

  • 제한 시 429와 함께 안내 메시지, Retry-After 제공

  • 클라이언트가 자체적으로 요청을 조절할 수 있도록 지원

  • HTTP/1.1 429 Too Many Requests
    X-RateLimit-Limit: 1000
    X-RateLimit-Remaining: 0  
    X-RateLimit-Reset: 1640995200
    Retry-After: 60
    
    {
      "error": "rate_limit_exceeded",
      "message": "API rate limit exceeded",
      "retry_after_seconds": 60
    }
(4) 클라이언트 설계 패턴
  • 클라이언트 측 캐시 활용 → API 호출 횟수 감소
  • 백오프(특히 지수 백오프)로 재시도
  • 임계치 이해 및 graceful fallback 구현

3. 참고

3-1. 지수 백오프 (Exponential Backoff)

(1) 정의

  • 네트워크 요청이 실패했을 때, 재시도 간격을 지수적으로 증가시키며 재시도하는 전략.
  • 예: 1초 → 2초 → 4초 → 8초 … 처럼 대기 시간이 점점 길어짐.

(2) 목적

  • 트래픽 폭주 방지: 많은 클라이언트가 동시에 무한 재시도를 하면 서버가 더 빨리 다운됨 → 백오프는 재시도를 분산시켜 서버 회복 시간을 벌어줌
  • 시스템 안정성 확보: 재시도 간격을 늘려 네트워크나 서버의 일시적 부하 완화
  • 비용 절감: 불필요한 실패 요청을 줄여 서버 리소스와 네트워크 비용 절약

(3) 실무적 특징

  • 보통 지수 증가 + 랜덤 지터(jitter)를 함께 사용
    • 단순 지수 증가만 하면 클라이언트들이 동시에 재시도하는 “스파이크(동기화 폭주)” 발생 가능
    • → 지터를 넣어 2초 ~ 3초, 4초 ~ 6초 범위 안에서 랜덤 대기 → 동기화 회피
  • 많이 쓰이는 곳: AWS SDK, Google Cloud API, TCP 네트워크 재전송 로직

3-2. Graceful Fallback

(1) 정의

  • 시스템이 장애나 제한 상황에 직면했을 때, 완전히 실패하지 않고 축소된 기능이나 대체 경로를 제공하는 전략
  • 즉, “최소한의 경험”을 보장하는 방식

(2) 목적

  • 사용자 경험 보호: 서비스 전체가 죽는 대신, 일부 기능만 제한적으로 제공
  • 안정성 강화: 특정 리소스(DB, API)가 장애나 Rate Limit에 걸려도 서비스의 핵심 기능은 계속 동작
  • 신뢰 확보: “완전 불가” 대신 “부분적 가능”을 제공 → 서비스에 대한 신뢰감 유지

(3) 실무적 특징

  • 예시
    • 트위터: API Rate Limit 초과 시, 최근 트윗 캐시를 보여주고 새 트윗은 잠시 불가
    • 전자상거래: 추천 서비스 장애 시, 기본 베스트셀러 목록 제공
    • 동영상 스트리밍: 서버 부하 시, 저화질 영상으로 자동 전환
  • Graceful Fallback은 단순한 에러 메시지(“서버 다운”)가 아니라, 대체 데이터/기능을 제공하는 점이 핵심

0개의 댓글