Поиск по сайту:

Как ограничить скорость соединений (запросов) в NGINX


В нашей последней статье из серии «Управление трафиком NGINX» мы обсуждали, как ограничить количество соединений в NGINX. В этом руководстве мы рассмотрим, как ограничить частоту запросов в NGINX.

Ограничение скорости – это метод управления трафиком, используемый для ограничения количества HTTP запросов, которые клиент может сделать за определенный период времени. Ограничения скорости рассчитываются в запросах в секунду (или RPS).

Примером запроса является запрос GET для страницы входа в приложение, запрос POST в форме входа или POST . на конечной точке API.

Существует множество причин ограничить частоту запросов к вашим веб-приложениям или службам API, одна из которых — безопасность: защита от неправомерных быстрых запросов.

Ограничение скорости соединений в NGINX

Начните с определения параметров ограничения скорости с помощью директивы limit_req_zone. Обязательными параметрами являются ключ для идентификации клиентов, зона общей памяти, в которой будет храниться состояние ключа и частота доступа к URL-адресу с ограниченным запросом, а также скорость.

Директива limit_req_zone действительна в контексте HTTP.

limit_req_zone $binary_remote_addr zone=limitreqsbyaddr:20m rate=10r/s;

Кроме того, установите код состояния ответа, который возвращается в отклоненные запросы, используя директиву limit_req_status, которая действительна в контексте HTTP, сервера и местоположения.

limit_req_status 429;

Теперь вы можете использовать директиву limint_conn, чтобы включить ограничение скорости запросов в контексте HTTP, сервера и местоположения. Он принимает зону памяти в качестве параметра и другие дополнительные параметры.

limit_req zone=limitreqsbyaddr;

В следующем примере конфигурации показано ограничение частоты запросов к API веб-приложения. Размер общей памяти составляет 20 МБ, а ограничение скорости запросов — 10 запросов в секунду.

upstream api_service {
    server 127.0.0.1:9051;
    server 10.1.1.77:9052;
}
limit_req_zone $binary_remote_addr zone=limitreqsbyaddr:20m rate=10r/s;
limit_req_status 429;

server {
    listen 80;
    server_name testapp.linux-console.net;
    root /var/www/html/testapp.linux-console.net/build;
    index index.html;

    #include snippets/error_pages.conf;
    proxy_read_timeout 600;
    proxy_connect_timeout 600;
    proxy_send_timeout 600;
    location / {
        try_files $uri $uri/ /index.html =404 =403 =500;
    }
    location /api {
        limit_req zone=limitreqsbyaddr;
        proxy_pass http://api_service;

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

       
   }
}

Сохраните файл конфигурации и закройте его.

Затем проверьте правильность синтаксиса конфигурации NGINX с помощью следующей команды:

sudo nginx -t

После этого перезагрузите сервис NGINX и примените последние изменения:

sudo systemctl reload nginx

Как только предел скорости 10 запросов в секунду превышается одним клиентом, обращающимся к /api/, NGINX возвращает сообщение «429 Слишком много запросов». ошибка клиенту.

Он также регистрирует инцидент в журнале ошибок.

2022/04/29 00:30:38 [error] 3145846#0: *131039 limiting requests, excess: 0.990 by zone "limitreqsbyaddr", client: 192.168.1.10, server: testapp.linux-console.net, request: "GET /api/v1/app/meta-data HTTP/1.1", host: "testapp.linux-console.net", referrer: "https://testapp.linux-console.net/"

Иногда, в зависимости от характера вашего приложения или API, клиенту необходимо сделать много запросов одновременно, а затем на некоторое время снизить скорость, прежде чем делать больше. NGINX также может буферизовать любые лишние запросы в очереди и оперативно их обрабатывать.

Вы можете включить это поведение при ограничении скорости, используя параметр burst с директивой limit_req. Чтобы включить организацию очереди без задержки, добавьте параметр nodelay.

limit_req zone=limitreqsbyaddr burst=20 nodelay;

Существует проблема с ограничением скорости на основе IP-адреса клиента, особенно для пользователей, получающих доступ к вашему приложению из той же сети и работающих за NAT. В этом случае все их запросы будут исходить с одного и того же IP-адреса. В таком сценарии вы можете использовать другие переменные для идентификации клиентов, например файл cookie сеанса.

Для получения дополнительной информации об ограничении скорости запросов ознакомьтесь с этим ограничением скорости NGINX на веб-сайте NGINX. Далее мы рассмотрим, как ограничить использование полосы пропускания в NGINX.