#python #tornado
Вопрос:
можно ли было бы реализовать функцию ограничения скорости в моем приложении tornado? например, ограничить количество HTTP-запросов от конкретного клиента, если они идентифицированы как отправляющие слишком много запросов в секунду (что указывает на то, что они являются ботами).
Я думаю, что мог бы сделать это вручную, сохранив запросы в базе данных и проанализировав запросы на IP-адрес, но я просто проверял, существует ли уже существующее решение для этой функции.
Я попытался проверить страницу торнадо на github, у меня те же вопросы, что и в этом посте, но явного ответа предоставлено не было. также проверил вики-ссылки торнадо, но я думаю, что ограничение скорости еще не обработано.
Комментарии:
1. Лучше обрабатывается в Nginx (простое однострочное решение): nginx.com/blog/rate-limiting-nginx .
Ответ №1:
Вместо того, чтобы хранить их в БД, было бы лучше хранить их в словаре, хранящемся в памяти, для удобства использования. Также вы можете поделиться информацией о том, есть ли в api балансировщик нагрузки и какой веб-сервер используется.
Ответ №2:
Решение вашей проблемы корпоративного уровня заключается ambassador
в следующем . Вы можете использовать решения ambassador, такие как прокси-сервер посланника и пограничный стек, и настроить его так, чтобы он выполнял необходимые функции.
в дополнение к разрыву данных вы можете использовать любую популярную кэшированную базу данных или файлы, которые хранятся как пары ключ:значение, например redis.
если вы делаете это для очень небольшого проекта, можете использовать некоторые пакеты npm/pip.
Прочитайте документы: https://www.getambassador.io/products/edge-stack/api-gateway/
Комментарии:
1. Спасибо. сейчас я буду проверять redis или memcached
Ответ №3:
Вероятно, вам следует сделать это до того, как ваши запросы достигнут Торнадо.
Но если это функция уровня приложения (ограничение запросов в зависимости от уровня подписки), то вы можете сделать это в Tornado множеством способов, в зависимости от того, насколько сложным вы хотите, чтобы ограничение скорости было.
Вероятно, самый простой способ — это указать на свой tornado.web.Application
адрес, который использует ip-адрес в качестве ключа и метку времени последнего запроса в качестве значения, и сверить каждый запрос с ним prepare
-если прошло недостаточно времени с момента последнего запроса, создайте tornado.web.HTTPError(429)
(в идеале с Retry-After
заголовком). Если вы сделаете это, вам все равно нужно будет время от времени удалять записи, которые не делали запрос в последнее время, или он будет расти (вы могли бы делать это finish
по каждому запросу).
Если у вас есть другое подключенное хранилище fast/in-memory (memcache, redis, sqlite), вам следует использовать его, но вам определенно не следует использовать СУБД, так как все эти записи не будут полезны для его производительности.