Nginx прокси-буферизация - изменение номера буфера и размера?

Мне было интересно и попытаться выяснить, как эти два параметра:

proxy_buffers [number] [size];

может влиять (улучшать/деградировать) производительность прокси-сервера и изменять ли размер буфера, или номер, или оба...?

В моем конкретном случае речь идет о системе, обслуживающей динамически генерируемые двоичные файлы, которые могут отличаться по размеру (~ 60 - 200 кБ). Nginx служит в качестве балансировки нагрузки перед 2 Tomcats, которые действуют как генераторы. Я видел в Nginx error.log, что при настройке размера буферов по умолчанию все проксированные ответы кэшируются в файл, поэтому я считаю логичным изменить параметр таким образом:

proxy_buffers 4 32k;

и предупреждающее сообщение исчезло.

Что мне непонятно здесь, если я должен предпочтительно установить 1 буфер с большим размером или несколькими меньшими буферами... Например:

proxy_buffers 1 128k; vs proxy_buffers 4 32k; vs proxy_buffers 8 16k; и т.д.

В чем может быть разница и как это может повлиять на производительность (если вообще)?

Ответ 1

Во-первых, стоит посмотреть, что в документации говорится о директивах:

http://nginx.org/r/proxy_buffers

Синтаксис: размер числа proxy_buffers;
По умолчанию: proxy_buffers 8 4k | 8k;
Контекст: http, сервер, местоположение

Устанавливает количество и размер буферов, используемых для чтения ответа от прокси-сервера, для одного соединения. По умолчанию размер буфера равен одной странице памяти. Это 4K или 8K, в зависимости от платформы.

Переход на уровень http://nginx.org/r/proxy_bufferring дает немного больше объяснений:

Когда буферизация включена, nginx получает ответ от проксируемого сервера как можно скорее, сохраняя его в буферах, установленных директивами proxy_buffer_size и proxy_buffers. Если весь ответ не помещается в память, его часть можно сохранить во временный файл на диске....

Когда буферизация отключена, ответ передается клиенту синхронно, сразу же после его получения....


Итак, что все это значит?

  1. Прежде всего, Nginx высоко оптимизирован, чтобы быть наиболее эффективным с ресурсами на кону. Хорошо известно использование наименьшего количества ресурсов для обслуживания каждого отдельного соединения. Дополнительное увеличение на 4 КБ на соединение было бы большим увеличением - насколько оно эффективно.

  2. Вы можете заметить, что размер буфера выбран равным размеру страницы рассматриваемой платформы. https://en.wikipedia.org/wiki/Page_(computer_memory) По сути, короче говоря, абсолютное лучшее число также может выходить за рамки этого вопроса в StackOverflow и может также сильно зависеть от операционной системы и Архитектура процессора.

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

    Например, я бы не стал устанавливать его в proxy_buffers 1 1024k, потому что тогда вы будете выделять буфер proxy_buffers 1 1024k для каждого буферизованного соединения, даже если содержимое все еще может легко поместиться в 4 КБ, потенциально тратя дополнительную память (хотя, конечно, существует также малоизвестный факт, что неиспользуемая, но выделенная память практически свободна с 1980-х годов) Вероятно, есть веская причина, по которой число буферов по умолчанию было выбрано равным 8.

  4. Увеличение буферов вообще может быть немного бессмысленным, если вы на самом деле делаете кэширование ответов этих двоичных файлов с помощью http://nginx.org/r/proxy_cache, потому что nginx все равно будет записывать его на диск для кэширования, и вы может также не тратить лишнюю память на буферизацию этих ответов.

    Хорошая операционная система должна быть способна уже выполнять надлежащее кэширование содержимого, записываемого на диск, с помощью функции буферного кэша файловой системы - см. Https://www.tldp.org/LDP/sag/html/buffer-cache..html (и, возможно, несколько странно названная статья по адресу https://en.wikipedia.org/wiki/Page_cache, так как имя "disk-buffer" уже было использовано для статьи об оборудовании для жесткого диска) - так что, вероятно, в этом нет особой необходимости дублирующая буферизация непосредственно в nginx. Вы также можете взглянуть на varnish-cache для некоторых дополнительных идей и идей по поводу многоуровневого кэширования и того факта, что хорошие операционные системы уже должны позаботиться о многих вещах, которые некоторые люди все еще пытаются ошибочно оптимизировать с помощью функциональности конкретного приложения.

  5. Точно так же, если вы на самом деле не выполняете кэширование ответов, вы также можете спросить себя, является ли буферизация приемлемой или нет.

    На самом деле буферизация может оказаться полезной для лучшей защиты ваших апстримов от вектора медленной атаки - https://en.wikipedia.org/wiki/Slowloris_(computer_security) - однако, если вы разрешите nginx иметь буферы мегабайтного размера, то по сути, вы начинаете выставлять сам nginx за использование неоправданного количества ресурсов для обслуживания клиентов со злонамеренными намерениями.

  6. Если ответы слишком велики, вы можете попытаться оптимизировать их на уровне ответов. Деление некоторого контента на отдельные файлы; делать сжатие на уровне файлов; делать сжатие с помощью gzip на уровне HTTP Content-Encoding и т.д.


TL; DR: это действительно довольно широкий вопрос, и существует слишком много переменных, которые требуют нетривиального исследования, чтобы найти абсолютный лучший ответ для любой конкретной ситуации.