API
Rate limiting: построй распределённый лимитер, который реально держит
Читать про ложь пер-нодового счётчика — не то же, что смотреть, как твой лимит тихо утроился в production. Построй лимитер, прогони его за балансировщиком на нескольких нодах, затем атакуй так, как делает реальный клиент — через границу окна и через все ноды разом — и докажи, что лимит держит.
Преврати ментальную модель юнита в работающий артефакт: распределённый token-bucket лимитер, чей счётчик живёт в Redis, чья проверка атомарна, а чей ответ 429 — корректный контракт, проверенный нагрузочным тестом, который побеждает наивный пер-нодовый лимитер.
Построй 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.
- Добавь вариант 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, чтобы граница сброса не стампедила. Построив его раз и увидев, как наивная версия проваливает кросс-нодовый тест, ты превращаешь ложь пер-нодового счётчика в то, что никогда не отправишь случайно.