awesome-everything EN
↑ Обратно к восхождению

API

Rate limiting: построй распределённый лимитер, который реально держит

Суть Практический проект — построй распределённый атомарный token-bucket лимитер в Redis, докажи, что он держит реальный лимит на нескольких нодах, и отправь корректный контракт 429.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 240 min

Читать про ложь пер-нодового счётчика — не то же, что смотреть, как твой лимит тихо утроился в production. Построй лимитер, прогони его за балансировщиком на нескольких нодах, затем атакуй так, как делает реальный клиент — через границу окна и через все ноды разом — и докажи, что лимит держит.

Цель

Преврати ментальную модель юнита в работающий артефакт: распределённый token-bucket лимитер, чей счётчик живёт в Redis, чья проверка атомарна, а чей ответ 429 — корректный контракт, проверенный нагрузочным тестом, который побеждает наивный пер-нодовый лимитер.

Проект
0 из 7
Цель

Построй rate-limiting middleware, который держит реальный пер-API-key лимит минимум на 3 app-нодах за балансировщиком через атомарный Redis token bucket, и докажи нагрузочным тестом, что глобальный лимит держит, а контракт 429 корректен.

Требования
Критерии приёмки
  • Результат до/после: наивный пер-нодовый лимитер пропускает ~N раз настроенный лимит под кросс-нодовым тестом; Redis token bucket пропускает в пределах малого допуска от настроенного лимита под идентичным тестом.
  • Захваченный ответ 429, показывающий статус, Retry-After и три заголовка RateLimit-* с RateLimit-Reset, выраженным в delta-seconds.
  • Доказательство атомарности проверки: тест конкурентности (много параллельных запросов по одному ключу) показывает отсутствие перепуска выше capacity, и показан Lua-скрипт, обрабатывающий весь read-decide-update.
  • Короткий разбор: какой алгоритм и пер-ключевое измерение ты выбрал и почему, измеренный глобальный лимит через ноды, и как jitter плюс непрерывное пополнение защищают от thundering herd.
Senior-стретч
  • Добавь вариант sliding-window-log для одного чувствительного эндпоинта (например, login) и сравни его след памяти на ключ с token bucket под той же нагрузкой.
  • Сделай лимитер fail open vs fail closed, когда Redis недоступен, измерь стоимость задержки Redis round trip на пути запроса и добавь локальный in-process fallback с задокументированным компромиссом.
  • Реализуй ярусные пер-ключевые quota (free vs paid), читаемые из конфига или заголовка, и покажи, что платный ключ получает больший burst и rate под тем же тестом.
  • Добавь защиту от злоупотреблений: пер-ключевую дневную quota поверх пер-минутного rate, и покажи, что клиент, исчерпавший дневную quota, удерживается, даже оставаясь под пер-минутным rate.
Итог

Это лимитер, который ты реально отправишь: счётчик живёт в Redis, поэтому все ноды его делят, проверка — один атомарный Lua-скрипт, поэтому конкурентные запросы не могут дважды потратить токен, алгоритм (token bucket) подходит бёрстовому реальному трафику, а отклонение — это контракт: 429 с Retry-After в delta-seconds, заголовки RateLimit-* и jitter, чтобы граница сброса не стампедила. Построив его раз и увидев, как наивная версия проваливает кросс-нодовый тест, ты превращаешь ложь пер-нодового счётчика в то, что никогда не отправишь случайно.

Продолжить восхождение ↑Проектирование и ревью публичного API от начала до конца
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.