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