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 mailing list
nginx-ru@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-ru