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

В настоящее время размер очереди составляет 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 составляет 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
задан 27 February 2018 в 16:18
1 ответ

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


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

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

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

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

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

Подробнее см .:


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

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

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


Выполните нагрузочные тесты , используя ab или siege .

3
ответ дан 3 December 2019 в 18:28

Теги

Похожие вопросы