upstream sent too big header while reading response header from upstream

Hennadii Makhomed gmm на csdoc.com
Чт Мар 6 06:05:33 UTC 2025


On 05.03.2025 21:29, Илья Шипицин wrote:

>> ведь никаких других способов кроме использования tcpdump
>> и использования error_log /var/log/nginx/error.log debug;
>> как я понимаю для поиска причины этой ошибки не существует?
> 
> я не пробовал, но приходит в голову вариант с "error_page
> 502=@some_location" и внутри some_location задать error_log
> возможно, что не сработает

server {
     root /home/www/example.com/public;
     location / { try_files $uri @backend; }
     location @backend { fastcgi_pass ...; error_page 502=@workaround; }
     location @workaround {
         if ($request_method = "POST") { return 500; }
         fastcgi_buffer_size 32k;
         fastcgi_buffers 16 32k;
         fastcgi_busy_buffers_size 64k;
         fastcgi_pass ... ;
     }
}

вместо того, чтобы вот такой workaround добавлять в каждый server { }
мне проще будет увеличить размеры fastcgi буферов в контексте http { }

>> или - имеет смысл не искать причину ошибки,
>> а просто увеличить размер буферов и все?
>>
> 
> увеличение размера буферов --> увеличение расхода памяти. если она есть в
> достатке, почему бы и нет.

виртуальной памяти - в достатке, ее много, swap раздел на 256
гигабайт внутри каждой виртуальной машины, при этом на диске
такой неиспользуемый swap раздел занимает физически мало места
- всего несколько мегабайт. так и придется сделать, похоже на то.

то есть, сейчас самый оптимальный алгоритм решения этой проблемы
с 502 ошибками, которые возвращает nginx такой: увеличивать
размеры fastcgi_buffer_size, fastcgi_buffers, fastcgi_busy_buffers_size
до тех пор, пока nginx не прекратит возвращать 502 статусы на овтеты
upstream.

неудобно в этой ситуации то, что нет возможности как-либо мониторить
сколько свободного места в буфере остается при обработке запросов,
и насколько близко nginx находится к той критической границе,
после которой он начнет сыпать 502 статусами, вместо нормальных ответов.
может быть размеры этих буферов слишком большие или наоборот, слишком
маленькие, и ситуация близкая к критической - это как можно узнать?

в самом идеальном варианте - лучше было бы чтобы nginx сам мог
бы добавить недостающие ему страницы буферов для обработки запроса,
и мог бы динамически увеличивать размер одного буфера, чтобы нормально
обработать ответ от upstream. например, идеальное решение проблемы:

сделать переменную fastcgi_max_buffer_size, по умолчанию равную 8
размерам переменной fastcgi_buffer_size, и в той ситуации, когда
размера fastcgi_buffer_size не хватает для обработки какого-то запроса -
динамически, "на лету" увеличивать размер буфера в два раза и продлжать
нормальную обработку запроса, до тех пор, пока не будет превышен размер
лимита fastcgi_max_buffer_size. И только при превышении этого лимита -
возвращать клиенту 502 статус вместо нормально ответа от upstream.

вопрос к разработчикам: можно ли так сделать? что мешает?


> к этому можно подойти творчески.
> fastcgi_buffer_size - это размер одного буфера. в один буфер
> предполагается, что должны поместиться все хедеры.
> а вот их количество увеличивать необязательно, и можно посмотреть в
> сторону  отключения fastcgi_buffering, и тогда
> запрос будет вычитываться постепенно.

отключить fastcgi_buffering нельзя, тогда такой веб-сервер будет уявзвим
к DDoS-атакам типа Slowloris и тогда будет очень мало смысла в наличии
nginx перед upstream сервером и сайт сможет обработать меньше запросов.

кстати, вариантов больше чем этих два:
	
fastcgi_buffering on;

fastcgi_buffering off;

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

fastcgi_max_temp_file_size 1024m;

но если поставить

fastcgi_max_temp_file_size 0;

то в таком случае на диск nginx ничего не будет писать,
но при этом - будет использовать буферизацию только в памяти.
и для большинства вариантов использования nginx - это более
предпочительный вариант чем fastcgi_buffering off;
потому что в режиме

fastcgi_buffering on;
fastcgi_max_temp_file_size 0;

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

только в очень небольшом количестве случаев может быть целесообразно
fastcgi_buffering off; - это когда backend написан на Go - но в таком
случае и nginx там не особо нужен вообще, можно напрямую софт на
Go выставить в интернет - в таком случае все накладные расходы
от промежуточного проксирования будут отсутствовать полностью.

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


а разве нет?

ведь с какой же целью nginx ставится перед backend? разве не для того,
чтобы максимально разгрузить backend и чтобы веб-сервер смог обработать
наибольшее количество запросов в секунду и выжать максимум из hardware?

количество worker-процессов php-fpm на backend очень сильно ограничено,
так что чем быстрее они обработают какой-либо запрос - тем будет лучше.

я такого не видел, чтобы кто-то ставил nginx перед backend не для того,
чтобы максимально разгрузить backend, а с прямо противоположной целью.

-- 
Best regards,
  Gena


Подробная информация о списке рассылки nginx-ru