Nginx · 2 min read · Oct 11, 2025

Ограничение скорости с Nginx

Эта статья объясняет, как использовать модуль HttpLimitReqModule в nginx для ограничения количества запросов для данной сессии. Это полезно, например, если ваш сайт подвергается атаке бота, который делает несколько запросов в секунду, тем самым увеличивая нагрузку на ваш сервер. С помощью HttpLimitReqModule вы можете определить лимит скорости, и если посетитель превышает этот лимит, он получит ошибку 503.

1 Использование HttpLimitReqModule

Откройте ваш nginx.conf…

nano /etc/nginx/nginx.conf

… и определите область, где хранятся состояния сессий - это должно находиться внутри контейнера http {}:

http {
    [...]
    limit_req_zone  $binary_remote_addr  zone=one:10m   rate=1r/s;
    [...]
}

Эта область называется one и выделяет 10 МБ памяти. Вместо переменной $remote_addr мы используем переменную $binary_remote_addr, которая уменьшает размер состояния до 64 байт. В 1 МБ зоне может быть около 16,000 состояний, поэтому 10 МБ позволяет хранить около 160,000 состояний, что должно быть достаточно для ваших посетителей. Лимит установлен на один запрос в секунду. Обратите внимание, что здесь необходимо использовать целые значения, поэтому, если вы хотите установить лимит на ползапроса в секунду, вы можете использовать 30r/m (30 запросов в минуту).

Чтобы применить этот лимит, мы используем директиву limit_req. Вы можете использовать эту директиву в контейнерах http {}, server {}, и location {}, но, на мой взгляд, она наиболее полезна в контейнерах location {}, которые передают запросы вашим серверным приложениям (PHP-FPM, mongrel и т.д.), потому что в противном случае, если вы загружаете одну страницу с множеством изображений, CSS и JavaScript файлов, вы, вероятно, превысите заданный лимит скорости с одним запросом страницы.

Итак, давайте поместим это в контейнер location ~ .php$ {}:

[...]
        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                include fastcgi_params;
                limit_req zone=one burst=5;
        }
[...]

limit_req zone=one burst=5; указывает, что этот лимит скорости принадлежит области хранения сессий, которую мы определили ранее (из-за zone=one), что означает, что лимит скорости составляет 1r/s. Вы можете представить себе значение параметра burst как своего рода очередь. Это означает, что если вы превышаете лимит скорости, последующие запросы задерживаются, и только если у вас в очереди больше ожидающих запросов, чем указано в параметре burst, вы получите ошибку 503 (например, как это:

Применение лимита скорости Nginx

).

Если вы не хотите использовать эту очередь (т.е. немедленно выдавать 503, если кто-то превышает лимит скорости), вы должны использовать параметр nodelay:

[...]
        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                include fastcgi_params;
                limit_req zone=one burst=5 nodelay;
        }
[...]

Не забудьте перезагрузить nginx, чтобы ваши изменения вступили в силу:

systemctl nginx reload

2 Ссылки

Share: X/Twitter LinkedIn

Get new posts in your inbox

No spam. Unsubscribe anytime.