17강 / 20강
트래픽 제어 — 몰려드는 요청을 다스리기
토큰 버킷 · 슬라이딩 윈도우 · 그리고 봇 막기
11강에서 큐를 배웠습니다. 하지만 큐도 한계가 있어요. 유입이 처리보다 계속 빠르면 큐는 결국 터집니다.
그럴 때 필요한 것이 유입 자체를 제한하는 것 — 속도 제한(rate limiting)입니다.
"타임세일 시작 3초 만에 서버가 멈췄습니다. 알고 보니 매크로 봇 한 대가 초당 2,000번씩 요청하고 있었어요."
이런 일은 실제로 매우 자주 일어납니다.
① 고정 윈도우 — 가장 단순하지만 허점이 있다
"1분에 60번까지" — 매 분이 시작되면 카운터를 0으로 되돌립니다.
고정 윈도우의 경계 문제. 실무에서 실제로 겪는 함정입니다.
Python
브라우저에서 실행
② 토큰 버킷 — 실무의 표준
양동이에 일정한 속도로 토큰이 떨어집니다. 요청이 오면 토큰 하나를 씁니다. 토큰이 없으면 거절.
양동이 크기가 순간적인 몰림을 얼마나 봐줄지를 정합니다(burst). 보충 속도가 평균 허용 속도고요. 이 두 숫자만 정하면 끝입니다.
순간 몰림은 받아 주고, 지속적인 과부하는 막는다 — 토큰 버킷의 장점입니다.
Python
브라우저에서 실행
🎮 토큰 버킷 시뮬레이터
보충 속도와 양동이 크기를 조절해 보세요. 정상 사용자와 봇을 동시에 흘려보내면서 봇은 막히고 정상 사용자는 통과하는 설정을 찾아 보세요.
무엇을 기준으로 제한할까
| 기준 | 장점 | 약점 |
|---|---|---|
| IP 주소 | 로그인 전에도 적용 가능 | 회사·학교는 여러 명이 한 IP를 공유 (억울한 차단) |
| 회원 ID | 정확함 | 비로그인 요청에는 못 씀 |
| API 키 | 외부 연동에 딱 맞음 | 내부 사용자엔 부적합 |
| 엔드포인트별 | 비싼 API만 강하게 제한 가능 | 설정이 복잡해짐 |
실무에서는 여러 개를 겹쳐서 씁니다 — "IP당 초당 20회 그리고 회원당 분당 300회 그리고 결제 API는 분당 5회".
제한 말고 다른 방법들
- 대기열 페이지 — 거절 대신 "앞에 3,241명 대기 중"을 보여 줍니다. 티켓 예매 사이트가 쓰는 방식이에요. 11강의 큐를 사람에게 보여 주는 것.
- 캐시 — 16강. 같은 요청이라면 애초에 서버까지 오지 않게 합니다.
- 서킷 브레이커 — 뒷단이 죽었으면 요청을 보내지 않고 즉시 실패시킵니다. 죽은 서버를 계속 두드려 봐야 회복만 늦어져요.
- 우아한 성능 저하 — 추천 목록 계산이 느리면 추천만 빼고 페이지를 보여 줍니다. 전체가 죽는 것보다 훨씬 낫습니다.
🤔 확인 문제
"1분에 60회" 고정 윈도우 제한의 대표적인 허점은?
해설 0:59에 60회, 1:00에 또 60회가 가능합니다. 2초에 120회가 통과하죠. 토큰 버킷이나 슬라이딩 윈도우가 이 문제를 해결합니다.
🤔 확인 문제
토큰 버킷에서 양동이 크기가 정하는 것은?
해설 보충 속도가 평균 허용치, 양동이 크기가 버스트 허용치입니다. 크기를 크게 하면 순간 몰림에 관대해져요.
🤔 확인 문제
요청을 제한해 거절할 때 함께 내려 줘야 할 것은?
해설 429 Too Many Requests + Retry-After입니다. 언제 다시 오라고 알려 주지 않으면 클라이언트가 즉시 재시도해 상황이 더 나빠져요.