Nginx и буферизация больших ответов

Nginx и буферизация больших ответов

В конфигурации нашего приложения nginx действует как обратный прокси-сервер перед gunicorn.

Наше приложение отвечает на запросы интерфейса, как правило, небольшими ответами... но некоторые конечные точки генерируют ответы, размер которых превышает одну страницу памяти (4 КБ).

Когда это происходит, nginx регистрирует следующее предупреждение:

an upstream response is buffered to a temporary file 
/path/to/nginx/proxy_temp/4/86/0000000864 while reading upstream, 
client: 1.2.3.4, server: api.ourdomain.com, request: "GET /pdf/..."

Наши логи nginx в конечном итоге переполнены этим предупреждением, и, насколько я могу судить, единственными решениями, которые позволят убрать это предупреждение из наших журналов, являются:плохие решения:

  • Я могу установить nginx proxy_max_temp_file_sizeна 0 — по сути, отключив буферизацию больших ответов. Это остановит буферизацию в файлы — но это также будет означать, что для конечных точек, генерирующих большие ответы (например, генерирующих PDF, которые создают ответы размером 1-2 МБ), медленно потребляющий клиент остановит соответствующий рабочий процесс gunicorn... Фактически, если есть N рабочих процессов gunicorn, потребуется всего N клиентов, генерирующих PDF-файлы за медленными сетевыми соединениями, и наше приложение будет отключено...

  • Я могу увеличить proxy_buffer_sizeдо более чем 4К (одна страница памяти, то есть). Я почти уверен, что это серьезно скажется на производительности nginx — 70% наших ответов действительно умещаются в 4К, и мы заставим nginx выделить... что? 2 МБ буферов для каждого из них, просто чтобы быть готовым к случайному запросу на генерацию PDF? РЕДАКТИРОВАТЬ: На самом деле это вообще не вариант - Майкл (ниже) прокомментировал, что единственными допустимыми значениями являются 4K и 8K.

  • Я мог бы отключить proxy_bufferingего, но это так же плохо, как и первое решение (медленные клиенты => смерть).

По сути, nginx заполняет наши логи тем, что нам НУЖНО — временной буферизацией в файлах, когда ответы большие.

Мы просто хотим, чтобы это не переполняло наши журналы, «отметив» это как не совсем предупреждение (я даже не уверен, почему это предупреждение — о какой «плохой вещи» оно нас предупреждает?)

Помимо редактирования nginxисходного кода и перекомпиляции, есть ли еще какие-то решения, которые я упускаю?

решение1

Это результат уровня логирования в директиве error_log Nginx.

https://www.nginx.com/resources/admin-guide/logging-and-monitoring/

error_log logs/error.log warn;

Регистрируются сообщения уровней «предупреждение», «критическая ошибка», «тревога» и «аварийная ситуация».

Настройка журнала ошибок по умолчанию работает глобально. Чтобы переопределить ее, поместите директиву error_log в основной (верхний уровень) контекст конфигурации. Настройки в основном контексте всегда наследуются другими уровнями конфигурации. Директива error_log может быть также указана на уровнях http, stream, server и location и переопределяет настройку, унаследованную от более высоких уровней.

Эта строка о буферизации находится на уровне предупреждений:

[warn] 30055#0: *1428 an upstream response is buffered to a temporary file 

Итак, если вы убедитесь, что уровень журнала ошибок не установлен на предупреждение, т. е. оставите его по умолчанию или уменьшите его, то вы больше не увидите это предупреждение. Любое из приведенных ниже решений подавит их:

Оставьте значение по умолчанию (уровень «ошибка» и выше):

error_log logs/error.log;

То же самое:

error_log logs/error.log error;

Вы также можете увеличить порог сверх error, до crit, alertи emerg.

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