NGINX: Поведение тайм-аута Request Limit для запросов в очереди (всплеск)

NGINX: Поведение тайм-аута Request Limit для запросов в очереди (всплеск)

В настоящее время размер очереди составляет 3000 запросов.

location /api/v2 {
     limit_req zone=bursted burst=3000;
     include /etc/nginx/proxy.conf;
 }

Ограничение скорости — 10 запросов в секунду.

 limit_req_zone $limit zone=api_slow:10m rate=1r/s;
 limit_req_zone $server_name zone=bursted:10m rate=10r/s;

Keep-Alive Timeout составляет 30 секунд. Другими словами, 2700 запросов должны отклоняться с кодом ошибки 408 каждые 30 секунд, когда очередь заполнена.

 reset_timedout_connection on;
 client_body_timeout 10;
 send_timeout 2;
 keepalive_timeout 30;

В час пик я не смог найти ни одного запроса в логах, который был отклонен NGINX с кодом ошибки 408 из-за тайм-аута, пока запрос ждал в очереди на пересылку в контейнер сервлетов. Только отклонение с кодом ошибки 503, что соответствует накладным расходам на запросы.

delaying request, excess: 2958.320, by zone "bursted"
limiting requests, excess: 3000.730 by zone "bursted"

Отклоняет ли NGINX запросы в таких очередях по таймауту, если они висят слишком долго? Что это за таймаут? Где его конфигурация?

решение1

Кажется, есть некоторая путаница в том, как работает ограничение скорости и таймауты nginx. Неттайм-аутдля ограничения скорости. Вы просто устанавливаете скорость и размер очереди. Любые запросы, превышающие скорость, добавляются в очередь для обработки позже. После того, как очередь полностью заполнится, любой дополнительный запрос будет отклонен с кодом статуса 503.


В вашем примеревы установили скорость 10 запросов в секунду (10r/s), размер пакета 3000, зона «разбита» размером 10 мегабайт. И этот предел скорости применяется как отдельный счетчик для каждого определенного сервера.

Другими словами, ваш сервер принимает и обрабатывает один запрос каждые 0,1 секунды и может поставить в очередь до 3000 превышающих запросов, которые затем обрабатываются с определенной скоростью: один каждые 0,1 секунды. И ваша burst zone может хранить около 160.000 IP-адресов.

Это значитесли в течение одной секунды поступает 3011 запросов, nginx немедленно обрабатывает первые 10 запросов, помещает в очередь еще 3000 запросов, а 3011-й запрос будет отклонен с кодом статуса 503. Затем очередь будет обрабатываться с заданной скоростью один запрос каждые 0,1 секунды. Пока не поступают новые запросы, очередь будет становиться короче, и в очередь снова можно будет добавлять новые запросы. Но пока в очереди уже находится 3000 запросов, каждый дополнительный запрос будет отклонен с кодом статуса 503.

Такое поведение линейной обработки очереди burst может привести к тому, что ваш сайт будет казаться медленным. Чтобы предотвратить это, вы можете добавить параметр nodelayв limit_req zone=bursted burst=3000 nodelay;. Это заставит все запросы из вашей очереди burst обрабатываться немедленно, при этом слоты в очереди будут помечены как «занятые», а затем снова «освобождаться» слот за слотом с определенной скоростью, так что определенный предел скорости будет достигнут с течением времени.

Кстати: вы можете изменить код статуса для отклоненных запросов с 503 на 444, добавив его limit_req_status 444;в свой httpблок конфигурации.

Более подробную информацию см. здесь:


Два таймаута из вашей конфигурации:

Заставит client_body_timeout 10;ваш сервер ждать до 10 секунд, пока клиентское тело не будет отправлено после запроса. Если в течение этого времени клиент не отправит тело, сервер закроет соединение с кодом статуса 408.

Это keepalive_timeout 30;заставит ваш сервер закрыть любое соединение с клиентом, которое все еще открыто, через 30 секунд. Но согласно моим тестам, время ожидания запроса в очереди burst не учитывается для keepalive_timeout.


Проведение нагрузочных тестовс использованиемабилиосада.

Связанный контент