- Вопрос или проблема
- Ответ или решение
- Ответ на вопросы по буферизации ответов в Nginx
- Вопрос 1: Как удалить [warn] и избежать буферизации ответов? Лучше выключить proxy_buffering или установить proxy_max_temp_file_size в 0? Почему?
- Вопрос 2: Если Nginx буферизует ответ, когда он отдает буферизованный ответ, кому и почему?
- Вопрос 3: Почему Nginx по умолчанию включает proxy_buffering и затем выдает [warn], если он фактически буферизует ответ?
- Вопрос 4: Когда ответ вызывает активацию этой опции? Когда это занимает больше времени, чем несколько секунд (сколько именно)? Это можно настроить?
- Рекомендации по настройке
- Заключение
Вопрос или проблема
У меня есть довольно большая и медленная (сложные данные, сложный интерфейс) веб-приложение, построенное на 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, но мне это кажется немного странным (мой прокси пытается буферизовать, но не имеет файла, в который можно буферизовать … как это может быть быстрее?).
Мои вопросы:
-
Как я могу убрать [warn] и избежать буферизации ответов? Лучше отключить
proxy_buffering
или установитьproxy_max_temp_file_size
в 0? Почему? -
Если
nginx
буферизует ответ: Когда он обслуживает буферизованный ответ, кому и почему? -
Почему
nginx
по умолчанию включаетproxy_buffering
, а затем [warn]ит вас, если он действительно буферизует ответ? -
Когда ответ вызывает эту опцию? Когда на обслуживание ответа уходит > каких-то секунд (сколько?)? Это можно настроить?
Заранее спасибо, ngw.
- Как я могу убрать [warn] и избежать буферизации ответов? Лучше отключить proxy_buffering или установить proxy_max_temp_file_size в 0? Почему?
Вам следует установить proxy_max_temp_file_size
в 0, чтобы убрать это. Директива proxy_buffering
не связана напрямую с предупреждением. Вы можете отключить ее, чтобы полностью прекратить любую буферизацию, но это не рекомендуется в общем случае (если это не нужно для Comet).
- Если nginx буферизует ответ, когда он обслуживает буферизованный ответ, кому и почему?
Он обслуживает ответ сразу, но клиент обычно имеет гораздо более медленное соединение и не может потреблять данные ответа так быстро, как они производятся вашим приложением. Nginx пытается буферизовать весь ответ, чтобы освободить ваше приложение как можно быстрее.
Смотрите также: http://aosabook.org/en/nginx.html
- Почему nginx по умолчанию включает proxy_buffering, а затем [warn]ит вас, если он действительно буферизует ответ?
Как я уже упоминал, proxy_buffering
не связано напрямую с предупреждением. Это в общем случае необходимо для оптимизированных операций прокси, и отключение этой функции ухудшает производительность и пропускную способность.
Nginx лишь предупреждает вас, когда ответ не помещается в настроенные память буферов. Вы можете игнорировать это предупреждение, если оно вас устраивает.
- Когда ответ вызывает эту опцию? Когда на обслуживание ответа уходит > чем какие-то секунды (сколько?)? Это можно настроить?
Это вызывается, когда память буферов заполнена. Пожалуйста, посмотрите документацию, там объяснен весь механизм: 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 может существенно повысить производительность вашего веб-приложения. Если у вас возникают проблемы с буферизацией, рекомендуется детально изучить рекомендации по настройкам и произвести тестирование на вашем окружении.