
Лимиты запросов и таймауты Nginx: настройка без маскировки проблем
Настраиваем client_max_body_size и proxy-таймауты Nginx по реальной операции, различаем 413, 499, 502 и 504 и проверяем медленный upstream.
Содержание
Пользователь загружает фотографию и получает 413, а долгий отчёт заканчивается 504. Эти ошибки относятся к разным этапам запроса: в первом случае Nginx отклонил слишком большое тело, во втором — не дождался данных от приложения за отведённое время.
Лимит следует выбирать по функции, а не увеличивать «до большого числа». client_max_body_size ограничивает объём тела запроса. proxy_connect_timeout задаёт ожидание соединения с приложением, а proxy_send_timeout и proxy_read_timeout — допустимые паузы при передаче. Сначала соберём требования, затем настроим только нужный маршрут.
Составьте бюджет запроса
Запишите ожидаемые значения до редактирования:
- максимальный полезный размер загрузки;
- обычное и предельное время ответа endpoint;
- время соединения с локальным или сетевым upstream;
- лимит внешнего CDN/балансировщика;
- лимит и timeout самого приложения;
- число одновременных тяжёлых запросов.
Самый маленький предел в цепочке определит результат. Если CDN допускает меньше, изменение Nginx не поможет. Если приложение принимает 10 MiB, разрешение 1 GiB на proxy только увеличит поверхность расхода ресурсов.
Ограничьте размер тела
Если только один маршрут принимает аватары, задайте предел внутри его location. В примере Nginx допускает тело до 8 МБ и передаёт запрос локальному приложению:
location /api/avatar {
client_max_body_size 8m;
proxy_pass http://127.0.0.1:3000;
}
Значение — пример, а не рекомендация для любого сайта. Выберите его по реальной функции и небольшому техническому запасу. При превышении Nginx возвращает 413. У приложения должна быть понятная пользовательская ошибка и собственная проверка типа и содержимого файла: размер не заменяет валидацию.
Большое тело может буферизоваться во временный файл. Контролируйте свободное место, права временных каталогов и I/O. Не отключайте request buffering без понимания поведения upstream и повторных попыток.
Разделяйте этапы ожидания
Для обычных API-запросов задайте отдельные пределы соединения, отправки запроса и чтения ответа. Числа ниже нужны для объяснения директив и должны быть заменены после измерения вашего приложения:
location /api/ {
proxy_pass http://127.0.0.1:3000;
proxy_connect_timeout 3s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
Эти цифры иллюстративны. proxy_connect_timeout ограничивает установление соединения. Для локального healthy upstream оно обычно быстрое; долгий connect может означать переполненную очередь или сетевую проблему.
proxy_send_timeout действует между последовательными операциями отправки запроса к upstream, а proxy_read_timeout — между чтениями ответа. Последний не является общим дедлайном. Streaming endpoint способен передавать данные дольше, пока паузы не превышают лимит.
Таймаут клиента и таймаут upstream — разные сущности. Директивы client_header_timeout и client_body_timeout ограничивают паузы при чтении запроса от клиента. Не сокращайте их глобально без теста медленных, но законных соединений.
Интерпретируйте коды вместе с журналом
- 413 — тело превышает допустимый размер;
- 499 в журнале Nginx — клиент закрыл соединение до ответа;
- 502 — Nginx не получил корректный ответ upstream или не подключился;
- 504 — истекло ожидание upstream;
- 408 — timeout при чтении клиентского запроса.
Код — начало расследования. 499 может означать нетерпеливого пользователя, timeout внешнего балансировщика или очень медленное приложение. 504 после роста proxy_read_timeout может лишь наступить позже.
Добавьте измеримые поля
Чтобы понять, на каком этапе прошло время, добавьте в контекст http отдельный формат access log. Он запишет полное время запроса и три измерения взаимодействия с upstream:
log_format timing '$remote_addr "$request" status=$status '
'rt=$request_time uct=$upstream_connect_time '
'uht=$upstream_header_time urt=$upstream_response_time '
'us=$upstream_status';
Включите его для нужного server и соберите достаточный период. $request_time охватывает взаимодействие Nginx с клиентом, а upstream-поля помогают отделить connect, получение заголовка и полный ответ приложения.
Не добавляйте request body, Authorization или cookies в журнал. Query string тоже может содержать секреты — это нужно учитывать при выборе $request.
Как исправлять долгую операцию
Если отчёт действительно формируется минуты, HTTP-запрос часто не должен ждать всё время. Приложение может поставить задачу в очередь, вернуть идентификатор и предоставить статус или готовый файл позже. Это освобождает workers и делает поведение управляемым.
Для обычного endpoint проверьте запрос базы, внешние API, pool соединений, блокировки и лимит workers. Увеличивайте timeout только после подтверждения, что операция законна и ресурсы выдерживают параллелизм.
Проверка и откат
После изменения проверьте синтаксис, перечитайте конфигурацию, запросите быстрый служебный маршрут и посмотрите последние ошибки:
sudo nginx -t
sudo systemctl reload nginx
curl -I https://example.com/api/health
sudo tail -n 100 /var/log/nginx/error.log
Тест загрузки выполняйте безопасным файлом около границы: один ниже и один выше лимита. Для timeout используйте контролируемый тестовый endpoint, а не задержку production-пользователей. Сравните журналы Nginx и приложения.
При ухудшении верните предыдущий блок, выполните nginx -t и reload. Для общей схемы смотрите reverse proxy Nginx и диагностику по логам.
Наблюдение после изменения
Сравните период до и после: долю 413/499/502/504, p95 времени ответа, число активных соединений, очередь и память upstream. Среднее время скрывает редкие, но тяжёлые запросы. Один успешный curl подтверждает маршрут, но не устойчивость при параллельной загрузке.
Задайте оповещение по росту ошибок и насыщению, а не по единичному коду. Если предел нужен только административной операции, отделите endpoint и доступ к нему. Это не позволит большой timeout или upload стать значением по умолчанию для всего публичного API.
Первоисточники
- Nginx: core module — client_max_body_size и клиентские таймауты.
- Nginx: proxy module — connect, send и read timeout и их точная семантика.
Самопроверка
Проверьте, что материал усвоен
Ответьте на все вопросы. Результат сохранится только в этом браузере и будет учтён в статистике прочитанных материалов.
Разбираем коротко
Частые вопросы
Почему увеличение proxy_read_timeout не ускоряет приложение?
Таймаут лишь позволяет Nginx дольше ждать данные от upstream. Он не уменьшает время вычисления и может удерживать больше соединений; сначала найдите медленный запрос по логам и метрикам приложения.
Что означает ошибка 413 Request Entity Too Large?
Тело запроса превышает client_max_body_size на одном из уровней. Значение нужно согласовать с приложением, внешним proxy и бизнес-ограничением, а не снимать лимит глобально.
Является ли proxy_read_timeout полным временем выполнения запроса?
Нет. Nginx измеряет паузу между последовательными операциями чтения ответа upstream. Если upstream периодически передаёт данные, общее соединение может жить дольше этого значения.


