nginx количество запросов в секунду

Несмотря на то, что поисковым ботам в файле robots.txt можно указать максимальное число запросов в секунду, а от большого количества POST-запросов на URL /edit можно защититься на уровне apache, если на VDS не используется apache, то имеет смысл ограничивать нагрузку при помощи nginx.

При использовании nginx для ограничения количества запросов в секунду можно использовать модуль ngx_http_limit_req_module, который

позволяет ограничить скорость обработки запросов по заданному ключу или, как частный случай, скорость обработки запросов, поступающих с одного IP-адреса.

http://nginx.org/ru/docs/http/ngx_http_limit_req_module.html

Пример конфигурации из документации nginx с пояснениями:

http {
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
...
server {
...
location /search/ {
limit_req zone=one burst=5;
}

limit_req zone=название [burst=число] [nodelay];

Задаем директивой limit_req зону разделяемой памяти (zone) и максимальный размер всплеска запросов (burst). В случае если скорость поступления запросов превышает указанную в зоне, то их обработка задерживается так, чтобы запросы обрабатывались с заданной скоростью. Избыточные запросы задерживаются до тех пор, пока их число не превысит максимальный размер всплеска. При превышении запрос завершается с ошибкой 503 (Service Temporarily Unavailable). По умолчанию максимальный размер всплеска равен нулю.

Директива limit_reg_zone задаёт параметры зоны разделяемой памяти, которая хранит состояние для разных значений ключа. Состояние в частности хранит текущее число избыточных запросов. Ключом является любое непустое значение заданной переменной (пустые значения не учитываются).
limit_req_zone $переменная zone=название:размер rate=скорость;
# пример использования
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

Это означает, что информация о состояниях сохраняется в зону “one” размером 10 мегабайт, а средняя скорость обработки запросов для этой зоны не должна быть более 1 запроса в секунду.

Т.е. для того, чтобы ограничить количество запросов в секунду nginx  следует:

  1. задать параметры зоны (в контексте http) директивой limit_req_zone $переменная zone=ZONE_NAME:10m rate=1r/s;
    в частности, для ограничения количества обращений по ip в качестве переменной использовать $binary_remote_addr
  2. указать зону (ZONE_NAME) из пункта 1 (в нужном контексте http/server/location) директивой limit_req zone для учета

Код отдаваемой ошибки можно переопределить директивой limit_req_status
limit_req_status 500;

Некоторые особенности настройки limit_req_zone и limit_req

Для примера - небольшой “cookbook” (сборник рецептов) для ограничения количества запросов в nginx. Профессионалам (да и тем, кто внимательно изучил документацию) - вряд ли откроется что-то новое. Однако, в качестве обзорного решения по некоторым возможностям модуля nginx. В примерах ниже используется сервер, на котором  установлен Nginx с php-fpm, однако, аналогичный вариант возможно воспроизвести и при настройке apache backend-ом к nginx.

http {
limit_req_zone $binary_remote_addr zone=phpzone:10m rate=2r/s;
}
server {
location ~ \.php$ {
limit_req zone=phpzone burst=5 nodelay;
try_files $uri $uri/ /index.php;
root /var/www/;
fastcgi_pass 127.0.0.1:9001;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}

Для файлов .php сделано ограничение 2 запроса в секунду с допустимым всплеском до 5 запросов в секунду. При этом обращение к другим location (статике, например - изображениям, css|txt и др.) не ограничивается.  Чтобы добавить определённые IP-адреса в исключения (адреса, для которых ограничение не действует) - например, 127.0.0.1 и 10.10.10.10 исползьуем geo и map модули
geo $limited_ip {
default 1;
127.0.0.1 0;
10.10.10.10 0;
}

map $limited_ip $limited_ip_key {
0 '';
1 $binary_remote_addr;
}
# и при указании переменной для phpzone используем $limited_ip_key
limit_req_zone $limited_ip_key zone=phpzone:10m rate=2r/s;

Пишем логи о превышении нагрузки в отдельный файл

Логами (а точнее уровнем логирования) в limit_req можно управлять при помощи директивы limit_req_log_level

синтаксис: limit_req_log_level info | notice | warn | error;
умолчание:
limit_req_log_level error;
контекст: http, server, location
Эта директива появилась в версии 0.8.18.

Настраиваем логирование ошибок 503 в отдельный файл (вариант наверняка не оптимальный)

limit_req_zone $binary_remote_addr zone=one:32m rate=2r/s;

error_page 500 501 502 504 =503 @offline50x;
error_page 503 =503 @offline503;
error_page 404 =503 @offline404;

server {
listen 80;

root /usr/share/nginx/html;
index index.html index.htm;

server_name localhost;

location / {
limit_req zone=one burst=10;
}

location @offline404 {
access_log /tmp/404;
try_files /offline.html =503;
}

location @offline50x {
access_log /tmp/50x;
try_files /offline.html =503;
}

location @offline503 {
access_log /tmp/ddos;
try_files /offline.html =503;
}

Метки:

Автор будет признателен, если Вы поделитесь ссылкой на статью, которая Вам помогла:
BB-код (для вставки на форум)

html-код (для вставки в ЖЖ, WP, blogger и на страницы сайта)

ссылка (для отправки по почте)

Комментарии (2) к записи “nginx количество запросов в секунду”

  1. levik сообщает :

    grep 'text' /path/to/access.log | cut -d' ' -f1 | sort | uniq -c | sort -r
    - анализ лога APACHE, На выходе отсортированный по убыванию пары IP и количество обращений. В grep помещаем любую интересующую фразу (HTTP Client, URL и тд)

  2. apt сообщает :

    спасибо!

Добавить комментарий