> Как реализовать rate limiting с использованием Redis (JavaScript)
Уровень: senior · Роль: frontend · Язык: JavaScript · Категория: Технические вопросы
Компании: QueenInteractiveGamesLtd
Стек: JavaScript, Node.js, Redis
> Пример ответа
Rate limiting с Redis обычно реализуется через два основных подхода: Sliding Window (скользящее окно) и Token Bucket (ведро токенов). Для Node.js чаще используют библиотеку ioredis.
Пример реализации Sliding Window с помощью Sorted Set:
JAVASCRIPTconst Redis = require('ioredis');const redis = new Redis();async function rateLimit(userId, maxRequests, windowMs) {const key = `rate_limit:${userId}`;const now = Date.now();const windowStart = now - windowMs;// Удаляем старые записи за пределами окнаawait redis.zremrangebyscore(key, 0, windowStart);// Получаем количество запросов в текущем окнеconst currentCount = await redis.zcard(key);if (currentCount >= maxRequests) {return { allowed: false, retryAfter: windowMs - (now - windowStart) };}// Добавляем новый запрос с временной меткойawait redis.zadd(key, now, `${now}-${Math.random()}`);await redis.expire(key, Math.ceil(windowMs / 1000));return { allowed: true };}// Использование:const result = await rateLimit('user123', 10, 60000); // 10 запросов в минутуif (!result.allowed) {// Вернуть 429 Too Many Requests}
Альтернатива - Token Bucket с помощью INCR и EXPIRE:
JAVASCRIPTasync function tokenBucket(userId, maxTokens, refillTime) {const key = `token_bucket:${userId}`;const current = await redis.incr(key);if (current === 1) {await redis.expire(key, refillTime); // Устанавливаем TTL при первом запросе}if (current > maxTokens) {return { allowed: false };}return { allowed: true };}
Ключевые моменты:
-
Используйте
MULTI/EXECдля атомарности в продакшене -
Устанавливайте TTL для автоматической очистки ключей
-
Для распределенных систем используйте Lua-скрипты для гарантии атомарности
-
Выбирайте подход в зависимости от требований: Sliding Window точнее, Token Bucket проще
> Похожие задачи по JavaScript
Как обеспечить корректную обработку запросов при параллельном выполнении для одного пользователя
Как спроектировать и реализовать rate limiting для платного API с разными тарифами
Можно ли использовать key вне рендеринга списков в React
Какой роутер используется в React: нативный или сторонний
> Похожие задачи по frontend
Как обеспечить корректную обработку запросов при параллельном выполнении для одного пользователя
Как спроектировать и реализовать rate limiting для платного API с разными тарифами
Что происходит при инициализации массива в React-компоненте при каждом рендере и почему это плохо?
Почему для внешних функций не нужен массив зависимостей в useEffect?
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью