Skip to content

속도 제한과 배압 제어

서론

쌍십일(광군제) 자정, 수억 명의 사용자가 동시에 몰려드는데 -- 서버가 버틸 수 있을까? 모든 시스템에는 처리 능력의 상한선이 있습니다. 요청량이 시스템 수용 능력을 초과할 때 제어하지 않으면, 결과는 모두가 서비스를 이용할 수 없게 된다는 것입니다. 속도 제한과 배압은 시스템이 "압도당하지 않도록" 보호하는 두 가지 방어선입니다.

이 글에서 배울 내용

이 장을 마치면 다음을 얻게 됩니다:

  • 속도 제한의 필요성: 시스템을 보호하기 위해 일부 요청을 능동적으로 거부해야 하는 이유
  • 속도 제한 알고리즘: 토큰 버킷, 누출 버킷, 슬라이딩 윈도우 세 가지 핵심 알고리즘의 원리와 차이
  • 배압 메커니즘: 업스트림 속도가 다운스트림을 초과할 때의 처리 전략
  • 다층 속도 제한: 클라이언트에서 게이트웨이, 서비스까지의 다층 속도 제한 아키텍처
  • 실전 능력: 어떤 시나리오에서 어떤 속도 제한 전략을 선택해야 하는지 파악
내용핵심 개념
제 1장속도 제한이 필요한 이유눈사태 효과, 서비스 보호
제 2장속도 제한 알고리즘토큰 버킷, 누출 버킷, 슬라이딩 윈도우
제 3장배압 제어버퍼, 폐기 전략, 탄력적 확장
제 4장다층 속도 제한 아키텍처클라이언트, 게이트웨이, 서버
제 5장실전 및 선택Nginx, Redis, Sentinel

0. 전경도: 왜 사용자를 "거부"해야 하는가?

이것은 매우 직관에 반하는 것 같습니다 -- 모든 사용자에게 잘 서비스해야 하지 않나요? 하지만 현실은: 일부 요청을 거부하지 않으면, 모든 요청이 실패하게 됩니다.

100명만 앉을 수 있는 레스토랑에 갑자기 1000명이 몰려든다고 상상해 보세요. 속도 제한을 하지 않으면, 1000명이 모두 식사를 할 수 있는 것이 아니라 주방이 붕괴하고 웨이터가 마비되어 1000명 모두 식사를 할 수 없게 됩니다. 올바른 방법은 입구에서 줄을 서서 속도 제한을 하여, 100명을 먼저 들여보내고 나머지는 대기시키는 것입니다.

속도 제한의 핵심 목표

  • 시스템 보호: 과부하로 인한 서비스 완전 불가 상태 방지
  • 공정한 분배: 수락된 요청이 정상적으로 처리되도록 보장
  • 우아한 성능 저하: 속도 제한된 요청은 명확한 429 상태 코드를 받으며, 타임아웃이나 500 오류가 아닙니다

1. 속도 제한 알고리즘: 세 가지 고전적 방안

속도 제한의 핵심 문제는: 단위 시간당 최대 몇 개의 요청을 통과시킬 것인가? 입니다. 다양한 알고리즘은 정확도, 버스트 트래픽 처리, 구현 복잡도 측면에서 각각의 장단점이 있습니다.

Rate Limiting Algorithm Comparison
Choose an algorithm, then send requests to observe the effect
Passed0
Rejected0
Tokens left5
Token bucket
Adds tokens to the bucket at a fixed rate. Each request consumes one token, and extra tokens are discarded when the bucket is full. It allows bursts when stored tokens are available.
알고리즘원리버스트 트래픽정확도구현 복잡도
토큰 버킷고정 속도로 토큰을 발행, 요청이 토큰을 소비허용(버킷에 비축분이 있는 경우)높음중간
누출 버킷요청이 대기열에 들어가 고정 속도로 처리허용하지 않음(완전히 평활화)높음중간
슬라이딩 윈도우윈도우 내 요청 수 통계부분 허용비교적 높음낮음
고정 윈도우시간 윈도우별 카운트경계에서 버스트 가능낮음가장 낮음

어떤 알고리즘을 선택할까?

  • API 속도 제한: 토큰 버킷이 가장 일반적이며, 합리적인 버스트 트래픽을 허용
  • 트래픽 셰이핑: 누출 버킷은 일정한 출력 속도가 필요한 시나리오에 적합
  • 간단한 카운팅: 슬라이딩 윈도우는 구현이 간단하여 대부분의 웹 애플리케이션에 적합

2. 배압 제어: 업스트림이 다운스트림보다 빠를 때

속도 제한이 해결하는 것은 "외부 요청이 너무 많은" 문제이고, 배압(Backpressure)이 해결하는 것은 "내부 구성 요소 간 속도 불일치" 문제입니다.

생산자가 데이터를 생성하는 속도가 지속적으로 소비자가 데이터를 처리하는 속도를 초과하면, 중간의 버퍼가 계속 팽창하여 결국 메모리 오버플로우나 데이터 손실을 초래합니다. 배압 메커니즘은 소비자가 생산자에게 "속도를 늦추라"고 역통지할 수 있게 합니다.

Backpressure Control
What happens when production is faster than consumption?
Produce rate:6/s
Consume rate:3/s
Producer
6/s
Buffer (0/20)
Running normally
Consumer
3/s
Backpressure strategies:
Drop strategy
Drop new data directly when the buffer is full
Example: log collection, real-time metrics
Blocking strategy
Make producers wait when the buffer is full
Example: Go channels, Java BlockingQueue
Sampling strategy
Process only part of the data and skip the rest
Example: downsampling high-frequency sensor data
Elastic scaling
Dynamically increase the number of consumers
Example: Kubernetes HPA autoscaling

배압의 네 가지 전략

  1. 폐기(Drop): 버퍼가 가득 차면 새 데이터나 오래된 데이터를 폐기하며, 실시간성이 높지만 손실을 허용할 수 있는 시나리오에 적합
  2. 차단(Block): 생산자를 일시 정지시키고, 소비자가 처리를 마친 후 계속 진행하며, 데이터 손실이 불가능한 시나리오에 적합
  3. 샘플링(Sample): 일부 데이터만 처리하며, 고빈도 데이터 스트림에 적합
  4. 탄력적 확장(Scale): 소비자 수를 동적으로 증가시키며, 클라우드 네이티브 환경에 적합

3. 다층 속도 제한 아키텍처

프로덕션 환경에서 속도 제한은 한 곳에서만 하는 것으로는 충분하지 않으며, 다층 방어가 필요하며 각 계층은 다른 세분성의 문제를 해결합니다.

계층위치속도 제한 세분성도구
클라이언트프론트엔드/앱버튼 디바운스, 요청 쓰로틀lodash.throttle, debounce
CDN/WAF엣지 노드IP 수준, 지역 수준Cloudflare Rate Limiting
API 게이트웨이입구 게이트웨이라우팅 수준, 사용자 수준Nginx limit_req, Kong
서버애플리케이션 내부인터페이스 수준, 리소스 수준Sentinel, Resilience4j
데이터베이스스토리지 계층연결 수, QPS연결 풀 설정, 슬로우 쿼리 서킷 브레이커

속도 제한의 HTTP 사양

속도 제한된 요청은 429 Too Many Requests 상태 코드를 반환해야 하며, 응답 헤더에 다음을 포함해야 합니다:

  • Retry-After: 클라이언트에게 재시도까지 권장 대기 시간(초 또는 날짜)
  • X-RateLimit-Limit: 속도 제한 상한
  • X-RateLimit-Remaining: 남은 할당량
  • X-RateLimit-Reset: 할당량 초기화 시간

4. 실전 선택

시나리오추천 방안설명
Nginx 입구 속도 제한limit_req_zone누출 버킷 알고리즘 기반, 설정이 간단
분산 속도 제한Redis + Lua 스크립트토큰 버킷 또는 슬라이딩 윈도우, 다중 인스턴스 카운트 공유
Java 마이크로서비스Sentinel / Resilience4j서킷 브레이커, 성능 저하, 핫스팟 속도 제한 지원
Node.js APIexpress-rate-limit사용이 간편하고 Redis 스토리지 지원
Go 서비스golang.org/x/time/rate표준 라이브러리 토큰 버킷 구현

요약

속도 제한과 배압은 시스템 안정성을 보호하는 두 가지 핵심 방어선입니다. 속도 제한은 외부 트래픽의 유입 속도를 제어하고, 배압은 내부 구성 요소의 처리 속도를 조정합니다.

이 장의 핵심 포인트를 되돌아보세요:

  1. 속도 제한의 필요성: 일부 요청을 거부하지 않으면 모든 요청이 실패합니다
  2. 세 가지 핵심 알고리즘: 토큰 버킷(버스트 허용), 누출 버킷(완전 평활화), 슬라이딩 윈도우(간단하고 정확)
  3. 배압 메커니즘: 폐기, 차단, 샘플링, 확장 네 가지 전략
  4. 다층 방어: 클라이언트에서 데이터베이스까지, 각 계층은 다른 세분성의 문제를 해결
  5. 429 사양: 속도 제한 시 표준 상태 코드와 속도 제한 헤더 정보 반환

더 읽어보기