Модуль ngx_http_limit_req_module

Пример конфигурации
Директивы
     limit_req
     limit_req_dry_run
     limit_req_log_level
     limit_req_status
     limit_req_zone
Встроенные переменные

Модуль ngx_http_limit_req_module (0.7.21) позволяет ограничить скорость обработки запросов по заданному ключу или, как частный случай, скорость обработки запросов, поступающих с одного IP-адреса. Ограничение обеспечивается с помощью метода “leaky bucket”.

Пример конфигурации

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 | delay=число];
Умолчание:
Контекст: http, server, location

Задаёт зону разделяемой памяти (zone) и максимальный размер всплеска запросов (burst). Если скорость поступления запросов превышает описанную в зоне, то их обработка задерживается так, чтобы запросы обрабатывались с заданной скоростью. Избыточные запросы задерживаются до тех пор, пока их число не превысит максимальный размер всплеска. При превышении запрос завершается с ошибкой. По умолчанию максимальный размер всплеска равен нулю. Например, директивы

limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

server {
    location /search/ {
        limit_req zone=one burst=5;
    }

позволяют в среднем не более 1 запроса в секунду со всплесками не более 5 запросов.

Если же избыточные запросы в пределах лимита всплесков задерживать не требуется, то следует использовать параметр nodelay:

limit_req zone=one burst=5 nodelay;

Параметр delay (1.15.7) задаёт лимит, по достижении которого избыточные запросы задерживаются. Значение по умолчанию равно нулю и означает, что задерживаются все избыточные запросы.

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

limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;
limit_req_zone $server_name zone=perserver:10m rate=10r/s;

server {
    ...
    limit_req zone=perip burst=5 nodelay;
    limit_req zone=perserver burst=10;
}

Директивы наследуются с предыдущего уровня конфигурации при условии, что на данном уровне не описаны свои директивы limit_req.

Синтаксис: limit_req_dry_run on | off;
Умолчание:
limit_req_dry_run off;
Контекст: http, server, location

Эта директива появилась в версии 1.17.1.

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

Синтаксис: limit_req_log_level info | notice | warn | error;
Умолчание:
limit_req_log_level error;
Контекст: http, server, location

Эта директива появилась в версии 0.8.18.

Задаёт желаемый уровень записи в лог случаев отказа в обработке запросов при превышении скорости и случаев задержек при обработке запроса. Задержки записываются в лог с уровнем на единицу меньшим, чем отказы, например, если указано “limit_req_log_level notice”, то задержки будут записываться в лог на уровне info.

Синтаксис: limit_req_status код;
Умолчание:
limit_req_status 503;
Контекст: http, server, location

Эта директива появилась в версии 1.3.15.

Позволяет переопределить код ответа, используемый при отклонении запросов.

Синтаксис: limit_req_zone ключ zone=название:размер rate=скорость [sync];
Умолчание:
Контекст: http

Задаёт параметры зоны разделяемой памяти, которая хранит состояние для разных значений ключа. Состояние в частности хранит текущее число избыточных запросов. В качестве ключа можно использовать текст, переменные и их комбинации. Запросы с пустым значением ключа не учитываются.

До версии 1.7.6 в качестве ключа можно было задать ровно одну переменную.

Пример использования:

limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

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

В качестве ключа используется IP-адрес клиента. Обратите внимание, что вместо переменной $remote_addr используется переменная $binary_remote_addr. Длина значения переменной $binary_remote_addr всегда равна 4 байтам для IPv4-адресов или 16 байтам для IPv6-адресов. При этом размер состояния всегда равен 64 байтам на 32-битных платформах и 128 байтам на 64-битных платформах. В зоне размером 1 мегабайт может разместиться около 16 тысяч состояний размером 64 байта или около 8 тысяч состояний размером 128 байт.

При переполнении зоны удаляется наименее востребованное состояние. Если и это не позволяет создать новое состояние, запрос завершается с ошибкой.

Скорость задаётся в запросах в секунду (r/s). Если же нужна скорость меньше одного запроса в секунду, то она задаётся в запросах в минуту (r/m), например, ползапроса в секунду — это 30r/m.

Параметр sync (1.15.3) разрешает синхронизацию данной зоны разделяемой памяти.

Параметр sync доступен как часть коммерческой подписки.

Дополнительно, как часть коммерческой подписки, информацию о состоянии каждой такой зоны разделяемой памяти можно получить или сбросить при помощи API начиная с версии 1.17.7.

Встроенные переменные

$limit_req_status
хранит результат ограничения скорости поступления запросов (1.17.6): PASSED, DELAYED, REJECTED, DELAYED_DRY_RUN или REJECTED_DRY_RUN