Разработка ограничителя скорости
Dec 04 2022
Вот мои заметки о разработке ограничителя скорости. Что такое ограничитель скорости? 1- Token Bucket 2- Утечка ссылок на Bucket.

Вот мои заметки о разработке ограничителя скорости.
Что такое ограничитель скорости?
- В компьютерных сетях ограничение скорости используется для контроля скорости запросов, отправляемых или получаемых контроллером сетевого интерфейса .
- На стороне HTTP ограничивает количество клиентских запросов, которые разрешено отправлять за указанный период.
- Пользователи могут создавать 1 тикет каждые 5 минут.
- Пользователи могут создавать 2 учетные записи в день с одним и тем же IP-адресом.
- Пользователи могут совершать 5 неудачных попыток входа в систему в час с одного и того же IP-адреса в день.
- Ограничитель скорости предотвращает DoS-атаки
- Остановить злоупотребление системой
- Снижает стоимость
- Это предотвращает перегрузку серверов. Также снижает нагрузку на сервер
- Улучшите пользовательский опыт с меньшим трафиком
- Ограничитель скорости не должен замедлять время ответа HTTP вашей системы.
- Используйте меньше памяти
- Показывать исключения пользователям, когда их запросы блокируются из-за ограничения скорости.
- Ваш ограничитель скорости не должен влиять на всю систему. Например, если ваш кеш-сервер выходит из строя, ваша система должна быть доступна.
- Существуют различные способы реализации ограничителя скорости. Это; Реализация на стороне клиента, реализация на стороне сервера и альтернативный способ с использованием стороннего шлюза API.
- Как правило, клиентская сторона — ненадежное место для принудительного ограничения скорости.
- Реализация на стороне сервера имеет некоторые внутренние преимущества, поскольку вы можете изменить логику на своей стороне.
- Использование стороннего API-шлюза иногда полезно, потому что для его внедрения требуется время.
1- Ведро с жетонами
- Два основных параметра; Размер ковша и скорость наполнения.
- Размер корзины: максимально допустимое количество токенов.
- Скорость пополнения: количество токенов, помещаемых в ведро с любым интервалом, например каждую секунду.
- Предполагая, что у нас есть ведро, емкость определяется как количество токенов, которое оно может вместить. Всякий раз, когда потребитель хочет получить доступ к конечной точке API, он должен получить токен из корзины. Токен удаляется из корзины, если он доступен, и принимает запрос. Если токен недоступен, сервер отклоняет запрос.
- Через каждый фиксированный интервал нам нужно пополнять запасы.
- Если нам нужно регулировать HTTP-запросы на основе IP-адресов, для каждого IP-адреса требуется ведро.
- Может вызвать состояние гонки в распределенной среде (недостаток)

2- Протекающее ведро
- Когда приходит HTTP-запрос, система проверяет очередь. Если очередь не заполнена, запрос добавляется в очередь. В противном случае запрос блокируется.
- HTTP-запросы извлекаются из очереди и обрабатываются через равные промежутки времени.
- Обработка первого элемента в очереди происходит через регулярные промежутки времени или в порядке поступления (FIFO).
- Разделяет временную шкалу на временные окна фиксированного размера.
- Каждый запрос увеличивает счетчик.
- Временное окно считается от начала единицы времени до конца единицы времени.
- Пространственная сложность: O(1) — Сохранение текущего количества окон. Временная сложность: O(1) — Получение и простая операция атомарного приращения.
- Самая большая проблема заключается в том, что потребители могут найти время сброса и максимизировать запрос за небольшой период времени, когда они могут его бомбардировать.

- у алгоритма фиксированного окна есть проблема, как я писал. Это позволяет большему количеству запросов проходить по краям окна. Скользящее окно журнала решает эту проблему.
- сохраняет время запросов, отсортированное в наборе или таблице (например, Redis)
- Каждую минуту мы ищем старые запросы и отфильтровываем их. Затем рассчитать доступность. Если запрос превысит пороговую скорость, он удерживается, в противном случае он обслуживается.
- Потребляет много памяти.
- Дорого хранить неограниченное количество журналов для каждого запроса.
- Сложность пространства: O (максимальное количество запросов за время окна) — сохраняет все временные метки запросов во временном окне.
- Сложность времени: O (максимальное количество запросов за время окна) — удаление подмножества временных меток.
- Подсчитайте общее количество элементов в отсортированном наборе. Отклонить запрос, если это значение больше, чем наш предел регулирования «3».
- Вставьте текущее время в отсортированный набор и примите запрос.

- сочетает в себе низкую стоимость обработки алгоритма фиксированного окна и улучшенные граничные условия скользящего журнала.
- Сложность пространства: O (количество ведер)
- Сложность по времени: O(1) — извлекает последний сегмент, увеличивает и проверяет общую сумму сегментов (может храниться в переменной totalCount).
- Подробности реализации вы можете прочитать в этой статье.
- Еще одна статья для лучшего понимания.
- Удалите все счетчики старше 1 минуты.
- увеличить счетчик, если запрос поступает в текущем сегменте.
- Заблокированный запрос, если текущее ведро уже превысило лимит горла.

использованная литература
- https://www.quinbay.com/blog/rate-limiter-implementation-token-bucket-algorithm
- https://betterprogramming.pub/4-rate-limit-algorithms-every-developer-should-know-7472cb482f48
- https://codeminion.hashnode.dev/rate-limiting-algorithms
- https://goalgorithm.wordpress.com/2019/06/08/designing-an-api-rate-limiter/