входящий ответ буферизуется во временный файл

Вопрос или проблема

У меня есть довольно большая и медленная (сложные данные, сложный интерфейс) веб-приложение, построенное на RoR и обслуживаемое Puma с nginx в качестве обратного прокси.
Смотря на журнал ошибок nginx, я вижу довольно много записей, похожих на:

2014/04/08 09:46:08 [warn] 20058#0: *819237 ответ upstream буферизуется во временный файл 
    /var/lib/nginx/proxy/8/47/0000038478 во время чтения upstream, 
    клиент: 5.144.169.242, сервер: engagement-console.foo.it, 
    запрос: "GET /elements/pending?customer_id=2&page=2 HTTP/1.0", 
    upstream: "http://unix:///home/deployer/apps/conversationflow/shared/sockets/puma.sock:/elements/pending?customer_id=2&page=2", 
    host: "ec.reputationmonitor.it", 
    referrer: "http://ec.foo.it/elements/pending?customer_id=2&page=3"

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

Я знаю о proxy_max_temp_file_size и установке его в 0, но мне это кажется немного странным (мой прокси пытается буферизовать, но не имеет файла, в который можно буферизовать … как это может быть быстрее?).

Мои вопросы:

  1. Как я могу убрать [warn] и избежать буферизации ответов? Лучше отключить proxy_buffering или установить proxy_max_temp_file_size в 0? Почему?

  2. Если nginx буферизует ответ: Когда он обслуживает буферизованный ответ, кому и почему?

  3. Почему nginx по умолчанию включает proxy_buffering, а затем [warn]ит вас, если он действительно буферизует ответ?

  4. Когда ответ вызывает эту опцию? Когда на обслуживание ответа уходит > каких-то секунд (сколько?)? Это можно настроить?

Заранее спасибо, ngw.

  1. Как я могу убрать [warn] и избежать буферизации ответов? Лучше отключить proxy_buffering или установить proxy_max_temp_file_size в 0? Почему?

Вам следует установить proxy_max_temp_file_size в 0, чтобы убрать это. Директива proxy_buffering не связана напрямую с предупреждением. Вы можете отключить ее, чтобы полностью прекратить любую буферизацию, но это не рекомендуется в общем случае (если это не нужно для Comet).

  1. Если nginx буферизует ответ, когда он обслуживает буферизованный ответ, кому и почему?

Он обслуживает ответ сразу, но клиент обычно имеет гораздо более медленное соединение и не может потреблять данные ответа так быстро, как они производятся вашим приложением. Nginx пытается буферизовать весь ответ, чтобы освободить ваше приложение как можно быстрее.

Смотрите также: http://aosabook.org/en/nginx.html

  1. Почему nginx по умолчанию включает proxy_buffering, а затем [warn]ит вас, если он действительно буферизует ответ?

Как я уже упоминал, proxy_buffering не связано напрямую с предупреждением. Это в общем случае необходимо для оптимизированных операций прокси, и отключение этой функции ухудшает производительность и пропускную способность.

Nginx лишь предупреждает вас, когда ответ не помещается в настроенные память буферов. Вы можете игнорировать это предупреждение, если оно вас устраивает.

  1. Когда ответ вызывает эту опцию? Когда на обслуживание ответа уходит > чем какие-то секунды (сколько?)? Это можно настроить?

Это вызывается, когда память буферов заполнена. Пожалуйста, посмотрите документацию, там объяснен весь механизм: http://nginx.org/r/proxy_max_temp_file_size

Возможно, вам стоит увеличить размеры буферов.

Следующая конфигурация хорошо работает на моем сервере.

proxy_buffers 16 16k;  
proxy_buffer_size 16k;

Команда sendfile в nginx может помочь с этим для статического контента

https://docs.nginx.com/nginx/admin-guide/web-server/serving-static-content/

Включение sendfile:

По умолчанию NGINX сам обрабатывает передачу файлов и копирует файл в буфер перед отправкой. Включение директивы sendfile устраняет этап копирования данных в буфер и позволяет непосредственно копировать данные с одного файлового дескриптора на другой. Чтобы предотвратить полное занятие рабочего процесса одним быстрым соединением, вы можете использовать директиву sendfile_max_chunk, чтобы ограничить объем передаваемых данных за один вызов sendfile() (в этом примере до 1 МБ):

location /mp3 {
    sendfile           on;
    sendfile_max_chunk 1m;
    #...
}

Добавьте это в файл конфигурации nginx.conf или в контекст конфигурационного файла виртуального хоста (http, server, location):

proxy_max_temp_file_size 10240m;
proxy_buffers 240 240k;
proxy_busy_buffers_size 240k;
proxy_buffer_size 240k;

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

У меня была та же проблема, и я тестировал эти конфигурации для скрипта с интенсивным и длительным I/O, SQL и php процессами, и это сработало хорошо.

Никакой из этих ответов не решил мою проблему, потому что прокси-буферы не были проблемой. Мне просто нужно было кэшировать больше данных от PHP-FPM, прежде чем они были отправлены обратно клиенту.

В моем случае эта директива решила проблему:

client_body_buffer_size 256k;

По умолчанию это обычно около 16 кБ, но этого было недостаточно для моего PHP сайта.

Ответ или решение

Ответ на вопросы по буферизации ответов в Nginx

Вопрос 1: Как удалить [warn] и избежать буферизации ответов? Лучше выключить proxy_buffering или установить proxy_max_temp_file_size в 0? Почему?

Для устранения предупреждения можно установить proxy_max_temp_file_size в 0. Директива proxy_buffering не связана напрямую с этим предупреждением. Отключение буферизации (proxy_buffering off) может привести к снижению производительности, так как это мешает Nginx эффективно освобождать ресурсы вашего приложения. Однако если у вас специфические требования, которые требуют отключения буферизации (например, работа с Comet-технологиями), то это допустимо.

Вопрос 2: Если Nginx буферизует ответ, когда он отдает буферизованный ответ, кому и почему?

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

Вопрос 3: Почему Nginx по умолчанию включает proxy_buffering и затем выдает [warn], если он фактически буферизует ответ?

proxy_buffering включен по умолчанию, чтобы оптимизировать проксирование и максимизировать пропускную способность. Предупреждение [warn] возникает только тогда, когда ответ превышает объем памяти, отведенной для буферов, что свидетельствует о том, что сервер не может обработать ответ в памяти. Игнорировать это предупреждение можно, если оно не мешает вашему приложению.

Вопрос 4: Когда ответ вызывает активацию этой опции? Когда это занимает больше времени, чем несколько секунд (сколько именно)? Это можно настроить?

Активация буферизации происходит в зависимости от заполнения памяти буферов. Когда ответ превышает установленное количество памяти (например, proxy_buffers), Nginx начинает записывать ответ во временный файл. Время, которое ответ занимает для инициации этого процесса, зависит от размера самого ответа, а не от времени исполнения. Настройка возможна через директивы, например, proxy_buffer_size и proxy_buffers.

Рекомендации по настройке

Если вы столкнулись с подобной проблемой, можно протестировать следующие настройки:

proxy_buffers 16 16k;  
proxy_buffer_size 16k;

Эти значения могут варьироваться в зависимости от загрузки вашего приложения и характеристик сервера.

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

location /static {
    sendfile on;
}

Также стоит рассмотреть увеличение client_body_buffer_size, если ваша PHP-FPM не может обработать запросы.

client_body_buffer_size 256k;

Заключение

Правильная настройка Nginx может существенно повысить производительность вашего веб-приложения. Если у вас возникают проблемы с буферизацией, рекомендуется детально изучить рекомендации по настройкам и произвести тестирование на вашем окружении.

Оцените материал
Добавить комментарий

Капча загружается...