> Как спроектировать и реализовать rate limiting для платного API с разными тарифами (JavaScript)
Уровень: senior · Роль: frontend · Язык: JavaScript · Категория: Технические вопросы
Компании: QueenInteractiveGamesLtd
Стек: Node.js, JavaScript
> Пример ответа
Для проектирования rate limiting платного API с разными тарифами на Node.js я бы использовал комбинацию стратегий: Token Bucket (для гибкости) и Sliding Window (для точности). Основные шаги:
-
Архитектура хранения - Redis (быстрый, атомарные операции). Ключи:
rate_limit:{userId}:{tariff}:{timestamp_window}. -
Структура тарифов - хранить в конфиге или БД:
JAVASCRIPTconst tariffs = {free: { requests: 100, windowMs: 3600000 }, // 100/часpro: { requests: 10000, windowMs: 3600000 },enterprise: { requests: 100000, windowMs: 3600000 }};
- Middleware для Express:
JAVASCRIPTconst rateLimit = (req, res, next) => {const userId = req.user.id; // из JWTconst tariff = req.user.tariff || 'free';const { requests, windowMs } = tariffs[tariff];const key = `rl:${userId}:${tariff}`;// Используем MULTI для атомарностиconst now = Date.now();redis.multi().zremrangebyscore(key, 0, now - windowMs) // удаляем старые.zadd(key, now, `${now}-${Math.random()}`) // добавляем запрос.zcard(key) // считаем.expire(key, Math.ceil(windowMs / 1000)).exec((err, results) => {const count = results[2][1];if (count > requests) {return res.status(429).json({error: 'Too Many Requests',retryAfter: Math.ceil((windowMs - (now - oldestTimestamp)) / 1000)});}next();});};
- Ключевые моменты:
-
Используем sorted sets в Redis для скользящего окна.
-
Добавляем случайный суффикс к timestamp, чтобы избежать коллизий.
-
Для enterprise-тарифов можно увеличить лимиты и добавить burst-возможности (например, 1000 запросов за 1 секунду).
-
Мониторинг: логируем превышения лимитов и отправляем метрики в Prometheus.
- Масштабирование: при нескольких инстансах Redis обеспечивает консистентность. Для критичных API добавляем rate limiting на уровне Nginx (как первый барьер) и на уровне приложения (для точного биллинга).
> Похожие задачи по JavaScript
Какие подходы к оптимизации веб-приложений существуют
Как обеспечить корректную обработку запросов при параллельном выполнении для одного пользователя
Как реализовать rate limiting с использованием Redis
Можно ли использовать key вне рендеринга списков в React
> Похожие задачи по frontend
Какие подходы к оптимизации веб-приложений существуют
Как обеспечить корректную обработку запросов при параллельном выполнении для одного пользователя
Как реализовать rate limiting с использованием Redis
Что происходит при инициализации массива в React-компоненте при каждом рендере и почему это плохо?
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью