Создал распределенный rate-limiter в go, который поддерживает переменные лимиты скорости.
Сервис доступен здесь:
https://rate-limiter.rtprnshukla.ru/
(открыт, чтобы увидеть персика)
https://rate-limiter.rtprnshukla.ru/persik/userID=<int64>&userType=<normal/premium>
- Запрос от пользователя проходит через Лод Балансер
- Затем он направляет запрос к одному из трех экземпляров сервиса
- У каждой сервиса есть "Флуд-Контроль", который считывает глобальный кэш из redis
- Я добавил флуд-контроль в качестве мидлвейра к сервису.
redis:
address: 'redis:6379'
password: ''
db: 0
rate_limiter:
default_rate_limit:
rate: 8
window_seconds: 1s
user_types:
normal:
key_prefix: 'rl:normal'
rate_limit:
rate: 5
window_seconds: 1s
premium:
key_prefix: 'rl:premium'
rate_limit:
rate: 10
window_seconds: 1s
https://rate-limiter.rtprnshukla.ru/persik/userID=<int64>&userType=<normal/premium>
-
Eсли локально
http://localhost:8080/persik/userID=<int64>&userType=<normal/premium>
-
Usertype необходим для определения количества запросов
-
По умолчанию пользователю предоставляется rate 8, а затем window 1 секунда
-
Сервис также поддерживает обычных пользователей с другим тарифом
-
Сервис также поддерживает премиум-пользователей с другим тарифом
- клонируйте репозиторий, выполнив
git@github.com:shuklarituparn/flood-control-task.git
-
Выполните следующую команду
make setup
чтобы установить Golang и другие зависимости -
убедитесь, что у вас установлен docker
-
Выполните следующую команду
docker compose up
-
вы можете получить доступ к сервису по умолчанию в
http://localhost:8080
и встретиться с персиком -
вы также можете получить доступ к сервису через один из этих портов
http://localhost:8090
,http://localhost:8091
,http://localhost:8092
вы также можете использовать curl для тестирования сервиса
Реализовать интерфейс с методом для проверки правил флуд-контроля. Если за последние N секунд вызовов метода Check будет больше K, значит, проверка на флуд-контроль не пройдена.
-
Интерфейс FloodControl располагается в файле main.go.
-
Флуд-контроль может быть запущен на нескольких экземплярах приложения одновременно, поэтому нужно предусмотреть общее хранилище данных. Допустимо использовать любое на ваше усмотрение.
- Хотел выбрать tarantool, так как я являюсь Амбассадором VK и хотел использовать "наш" продукт (но выбрал redis для более быстрого прототипирования)
- Использовал Redis sorted sets (и sliding window method of rate limiting)
- Использовал nginx в качестве лод балансера
- Хотел сделать флуд-контрол на сайте лод балансера, чтобы получить элегантное решение, но из-за необходимости реализации интерфейса не смог этого сделать