NGINX - дроссельные запросы для предотвращения злоупотреблений

28

Причина, по которой я хочу это сделать, заключается в том, что пользователи разрабатывают против нашего API с помощью JavaScript, а некоторые разработчики облажаются и заставляют посетителей захлопывать сервер с помощью запросов AJAX. Когда это происходит, я хочу иметь возможность регулировать запросы API, возможно, до 50 запросов в минуту , или что-то в этом роде.

Примечание: (в частности, ресурсоемкие ресурсы БД, поэтому, возможно, на уровне пути, а не для всего сервера (например, throttle "/ json_api /", но не "/ static /").

orokusaki
источник

Ответы:

36

Это можно сделать с помощью LimitReqModule с Nginx. Однако, если это для обратного прокси, вы можете попробовать новое ограничение скорости, поддерживаемое HAProxy .

Я обнаружил, что ограничение скорости nginx немного сбивает с толку, чтобы получить точную скорость, которую вы хотите.

Но у вас есть что-то вроде:

limit_req_zone  $binary_remote_addr  zone=default:10m   rate=50r/m;

в httpразделе, а затем что-то вроде следующего в locationразделе в serverразделе:

limit_req zone=default burst=10 nodelay;

Чтобы не иметь его для определенного раздела, как /staticвы, просто сделайте его отдельным locationи не включайте в него limit_reqдирективу (или обратную).

Кайл Брандт
источник
Спасибо. Можете ли вы объяснить, что делают эти вещи (зона, пакет, нодлеев)? И вы хотели поставить zone=limit_req_zoneвместо этого?
orokusaki
Честно говоря, я не могу объяснить их так хорошо, поэтому я чувствую, что это просто запутывает. Объяснение Майкла в предоставленной мной ссылке звучит так, как будто это возможно. Я не верю, что у меня есть какие-либо опечатки, поскольку ваш второй вопрос ... Документация к модулю, на которую я ссылался, содержит пример, который может помочь.
Кайл Брандт
2
zone, burst и nodelay описаны на вики-странице Nginx о модуле ограничения скорости , ссылка на которую уже есть в ответе выше.
Марк Стосберг
Кайл, ты знаешь, есть ли способ объединить ограничение скорости для каждого местоположения с другим триггером (например, заголовок авторизации). В моем случае я могу захотеть ограничить скорость конкретного пользователя.
Нильс
1
@ Nils AFAICS, вы можете использовать $http_authorizationпеременную, чтобы определить новую зону, где ключом является такой заголовок, а не IP-адрес, т. Е., А limit_req_zone $http_authorization zone = per_user : 10m rate = 5r/sзатем использовать per_userзону в разделах местоположения, где вы хотите сделать ограничение на пользователя. Не проверенный, я только что прочитал документацию и список переменных nginx ... дайте мне знать, если вы попробуете это!
idrarig