Ответ
Rate Limiter — это механизм, предназначенный для контроля частоты запросов к системе, предотвращая её перегрузку и защищая от злоупотреблений (например, DDoS-атак).
Пример реализации на Python с использованием алгоритма Token Bucket:
import time
class RateLimiter:
def __init__(self, capacity: int, refill_rate: float):
"""
Инициализация Rate Limiter.
:param capacity: Максимальное количество токенов (запросов).
:param refill_rate: Скорость пополнения токенов в секунду.
"""
self.capacity = capacity
self.tokens = capacity
self.last_refill = time.time()
self.refill_rate = refill_rate # tokens per second
def allow_request(self) -> bool:
"""
Проверяет, разрешен ли запрос.
:return: True, если запрос разрешен, False иначе.
"""
now = time.time()
elapsed = now - self.last_refill
# Пополняем токены, но не превышаем capacity
self.tokens = min(self.capacity, self.tokens + elapsed * self.refill_rate)
self.last_refill = now
if self.tokens >= 1:
self.tokens -= 1
return True
return False
# Пример использования:
# limiter = RateLimiter(capacity=5, refill_rate=1) # 5 запросов, 1 токен/сек
# for _ in range(10):
# if limiter.allow_request():
# print("Request allowed")
# else:
# print("Request denied")
# time.sleep(0.5)
Сферы применения:
- API-сервисы (REST/gRPC): Защита от перегрузок, злоупотреблений и обеспечение справедливого использования ресурсов.
- Ограничение вызовов внешних API: Контроль над количеством запросов к сторонним сервисам (например, Telegram Bot API, платежные шлюзы) для соблюдения их лимитов.
Другие алгоритмы и готовые решения:
- Фиксированное окно (
Fixed Window): Разрешает N запросов в течение фиксированного временного интервала. Прост в реализации, но может быть уязвим к всплескам запросов в начале или конце окна. - Скользящее окно (
Sliding Window): Более сложный, но точный алгоритм, который учитывает запросы из предыдущего окна, обеспечивая более плавное ограничение. - Готовые решения: Для распределённых систем часто используются Redis с модулями типа
redis-cellили специализированные библиотеки, такие какFastAPI-Limiterдля Python-фреймворков.
Важно: В распределённых системах необходимо учитывать race conditions, поскольку одновременные запросы могут привести к некорректному состоянию лимитера. В таких случаях рекомендуется использовать распределённые хранилища (например, Redis) с атомарными операциями для обеспечения консистентности.
Ответ 18+ 🔞
А, слушай-ка, про Rate Limiter, да? Это ж та самая штука, которая, блядь, как вышибала в переполненном баре стоит. Подходит к тебе и говорит: «Ну-ка, полегче, дружок, ты у нас уже пятую кружку за минуту требуешь, давай-ка потише».
Вот смотри, как эта бандура в коде выглядит, на примере «Ведра с токенами»:
import time
class RateLimiter:
def __init__(self, capacity: int, refill_rate: float):
"""
Инициализация Rate Limiter.
:param capacity: Максимальное количество токенов (запросов).
:param refill_rate: Скорость пополнения токенов в секунду.
"""
self.capacity = capacity
self.tokens = capacity
self.last_refill = time.time()
self.refill_rate = refill_rate # tokens per second
def allow_request(self) -> bool:
"""
Проверяет, разрешен ли запрос.
:return: True, если запрос разрешен, False иначе.
"""
now = time.time()
elapsed = now - self.last_refill
# Пополняем токены, но не превышаем capacity
self.tokens = min(self.capacity, self.tokens + elapsed * self.refill_rate)
self.last_refill = now
if self.tokens >= 1:
self.tokens -= 1
return True
return False
Представь: у тебя есть ведро. В нём, допустим, 5 токенов-шариков. Каждый запрос — вытащил один шарик. А сверху капает водичка и новые шарики подкидывает, скажем, 1 шарик в секунду. Если шарики кончились — всё, братан, сиди и жди, пока накапает. Запросы упёрлись в пизду. Вот и вся магия, ёпта.
А где эту хрень применяют? Да везде, блядь!
- Твои APIшки: Чтобы какой-нибудь умник не начал слать тебе запросы со скоростью «хуй с горы» и не положил сервер, пока ты кофе пьёшь. Или чтобы все клиенты по-честному, а не кто первый встал — того и тапки.
- Когда ты сам лезешь в чужие API: Вот, например, пишешь бота для Телеграма. А они там, суки, лимиты ставят — не больше 30 сообщений в секунду. Вот ты и ставишь такого вышибалу перед своими запросами, чтобы не получить банхаммером по ебалу за «Too Many Requests».
Другие алгоритмы, там, для гурманов:
- «Фиксированное окно»: Всё просто, блядь. В течение минуты — не больше 100 запросов. Раз — и всё. Но есть подвох: если в последнюю секунду минуты набить 100 запросов, а в первую секунду следующей — ещё 100, то система, блядь, за секунду получит 200 запросов и накроется медным тазом. Не очень хитро.
- «Скользящее окно»: Это уже поумнее. Оно смотрит не на календарную минуту, а на последние 60 секунд в любой момент времени. Тут уже не проскочишь, хитрая жопа. Но и код сложнее, конечно.
- Готовые решения: Зачем, блядь, велосипед изобретать? Для распределённых систем бери Redis с каким-нибудь
redis-cell. Или, если на FastAPI сидишь, естьFastAPI-Limiter— прикрутил и забыл.
И главное, на что смотреть, ёпта: Если у тебя не один сервер, а целая орава, то race conditions, блядь, обеспечены. Два запроса в одно и то же время на разных машинах решат, что токен ещё есть, и оба пролезут. Для такого дела нужна одна точка правды — типа Redis, где операции атомарные. А то будет, как в том анекдоте: «А я думал, ты взял!».