- NGINX : Keep alive requests to static content ok — Keep alive requests to php-fpm requests hang until keepalive_timeout is reached
- 1 Answer 1
- Ускоряем Nginx за 5 минут
- NGINX : Keep alive requests to static content ok — Keep alive requests to php-fpm requests hang until keepalive_timeout is reached
- Related videos on Youtube
- محمّد محسن احمدی
NGINX : Keep alive requests to static content ok — Keep alive requests to php-fpm requests hang until keepalive_timeout is reached
FYI, the initial question I have posted is here, no need to read it as I was way off initially: https://serverfault.com/questions/427296/nginx-php-fpm-strange-issue-when-trying-to-display-images-via-php-gd-readf I was able to track it down to keep alives. Please bare in mind, when i speak of keep alives in this question, I mean USER NGINX keep alives. NOT NGINX BACKEND (php-fpm in this case). Scenario three is the problem scenario, I have just included one and two to be clear that I have done all the required testing. So, here is exactly what happens: Scenario one [ keep alive enabled ]: A) Request to static content [ non fastcgi based requerst, simple file system access ] is made B) Keep alives are on C) Content is sent no problem, 100% of the time Scenario two [ keep alive disabled ]: A) Request to dynamic php-fpm based content B) Keep alives are off C) Content is sent no problem, 100% of the time Scenario three [ keep alives enabled ]: A) Request to dynamic php-fpm based content B) Keep alives are on C) Content is sent, but the browser will hang in «loading state» until keepalive_timeout is reached. This state looks different accross browsers. For example, chrome will display the content, but will «spin» at the top browser. After keepalive_timeout is reached, spining stops and the request shows up in red in the debugger even tho the content is actually displayed fine. In IE the page remains blank until keep alive timeout is reached, and then the content shows up. Looking at the IE developer tools one sees the content takes «keepalive_timeout» seconds in «blue», which in IE developer tools case is «receiving». Stumped completly, tried reverting the conf to the most basic form and this still happens. To summerize, there appears to be some sort of network related issue (tcp/ip stack?) when serving php-fpm based results WITH keep alives enabled. Any ideas?
1 Answer 1
There’s likely one or two things at fault here.
syntax: fastcgi_keep_conn on | off; default: fastcgi_keep_conn off; context: http, server, location
By default, a FastCGI server will close a connection right after sending the response. When set to the value on, nginx will instruct a FastCGI server to keep connections open. This in particular is necessary for keepalive connections to FastCGI servers to function.
Enables keep-alive connections for the upstream.
Num specifies the max number of connections to keep open before, if the max is reached it will close the least recently used connections.
Single treats everything as a single host. With this flag connections to different backends are treated as equal.
Both are valid for Nginx 1.1.4 or newer
Ускоряем Nginx за 5 минут
Как правило, настроенный должным образом сервер Nginx на Linux, может обрабатывать 500,000 — 600,000 запросов в секунду. Но этот показатель можно весьма ощутимо увеличить. Хотел бы обратить внимание на тот факт, что настройки описанные ниже, применялись в тестовой среде и, возможно, для ваших боевых серверов они не подойдут.
На всякий пожарный, создадим бэкап исходного конфига.
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.orig vim /etc/nginx/nginx.conf
А теперь можно и похимичить!
Начнём с директивы worker_processes. Если Nginx выполняет работу нагружающую процессор (например SSL или gzipping), то оптимально установить эту директиву в значение, равное количеству ядер процессора. Выигрыш при большем значении вы получите только в случае обработки очень большого количества статики.
# This number should be, at maximum, the number of CPU cores on your system. worker_processes 24;
Также, директива worker_processes, умноженная на worker_connections из секции event, даст максимально возможное количество клиентов.
# Determines how many clients will be served by each worker process. worker_connections 4000;
Последняя пролетарская директива, которую я хочу затронуть — это worker_rlimit_nofile. Данная директива указывает сколько файловых дескрипторов будет использовать Nginx. На каждое соединение надо выделять по два дексриптора, даже для статических файлов (картинки/JS/CSS): один для соединения с клиентом, а второй — для открытия статического файла. Таким образом, значение worker_rlimit_nofile должно быть равным удвоенному значению Max Clients. В системе это значение можно установить из командной строки ulimit -n 200000 или используя /etc/security/limits.conf.
# Number of file descriptors used for Nginx. worker_rlimit_nofile 200000;
Теперь разберёмся с логированием. Во-первых, оставим логирование только критических ошибок.
# Only log critical errors. error_log /var/log/nginx/error.log crit
Если вы совсем бесстрашны и хотите отключить логирование ошибок целиком, то помните, что error_log off вам не поможет. Вы просто получите весь лог в файле off. Для отключения логирования ошибок надо делать так:
# Fully disable log errors. error_log /dev/null crit;
А вот логи доступа не так страшно отключить полностью.
# Disable access log altogether. access_log off;
Или, хотя бы, включить буфер чтения / записи.
# Buffer log writes to speed up IO. access_log /var/log/nginx/access.log main buffer=16k;
Для обработки подключений Nginx поддерживает ряд методов. Наиболее эффективным для Linux является метод epoll.
# The effective method, used on Linux 2.6+, optmized to serve many clients with each thread. use epoll;
Для того, чтобы Nginx пытался принять максимальное количество подключений, необходимо включить директиву multi_accept. Однако при слишком маленьком значении worker_connections, их лимит может быть очень быстро исчерпан.
# Accept as many connections as possible, after nginx gets notification about a new connection. multi_accept on;
- дескрипторах недавно открытых файлов: их размера и даты модификации;
- существовании директорий;
- ошибках при поиске файлов: отсутствие самого файла, отсутствие прав на чтение и т.д.
# Caches information about open FDs, freqently accessed files. open_file_cache max=200000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on;
Директива sendfile активирует копирование данных между файловыми дескрипторами средствами ядра, что намного эффективнее связки read() + write(), которая требует обмена данными с пользовательским пространством.
# Sendfile copies data between one FD and other from within the kernel. sendfile on;
После включения sendfile, можно заставить Nginx отправлять заголовки HTTP-ответов одним пакетом, а не отдельным частями.
# Causes nginx to attempt to send its HTTP response head in one packet, instead of using partial frames. tcp_nopush on;
Для keep-alive подключений можно выключить буферизацию (алгоритм Нейгла). Это будет полезно при частом запросе маленьких объёмов данных в режиме реального времени, без получения немедленного ответа, когда важна своевременная доставка данных. Классический пример — события наведения мышкой.
# Don't buffer data-sends (disable Nagle algorithm). tcp_nodelay on;
Стоит обратить внимание на ещё две директивы для keep-alive подключений. Их назначение выглядит очевидным.
# Timeout for keep-alive connections. Server will close connections after this time. keepalive_timeout 30; # Number of requests a client can make over the keep-alive connection. keepalive_requests 1000;
Чтобы высвободить дополнительную память, выделенную под сокеты, включите директиву reset_timedout_connection. Она разрешит серверу закрывать подключение тех клиентов, которые перестали отвечать.
# Allow the server to close the connection after a client stops responding. reset_timedout_connection on;
Ещё можно существенно уменьшить тайм-ауты для директив client_body_timeout и send_timeout (дефолтное значение обеих — 60 секунд). Первая — ограничивает время на чтение тела запроса от клиента. Вторая — время ответа клиенту. Таким образом, если клиент не начнёт читать данные в указанный промежуток времени, то Nginx закроет подключение.
# Send the client a "request timed out" if the body is not loaded by this time. client_body_timeout 10; # If the client stops reading data, free up the stale client connection after this much time. send_timeout 2;
И, конечно же, сжатие данных. Плюс — единственный и очевидный: уменьшение размера пересылаемого трафика. Минус — единственный и очевидный: не работает для MSIE 6 и ниже. Отключить сжатие для этих браузеров можно директивой gzip_disable, указав в качестве значения специальную маску “msie6”, которая соответствует регулярному выражению “MSIE 4\.”, но работает быстрее (спасибо hell0w0rd за комментарий).
# Compression. gzip on; gzip_min_length 10240; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml; gzip_disable "msie6";
Пожалуй, это всё, о чём я хотел рассказать. Скажу лишь ещё раз, что не стоит копировать приведенные настройки один в один. Я советую применять их по одной, каждый раз запуская какую-нибудь утилиту для нагрузочного тестирования (например, Tsung). Это весьма важно для понимания, какие настройки реально ускоряют ваш веб-сервер. Методичность в тестировании сэкономит вам уйму времени.
# This number should be, at maximum, the number of CPU cores on your system. worker_processes 24; # Number of file descriptors used for Nginx. worker_rlimit_nofile 200000; # Only log critical errors. error_log /var/log/nginx/error.log crit events < # Determines how many clients will be served by each worker process. worker_connections 4000; # The effective method, used on Linux 2.6+, optmized to serve many clients with each thread. use epoll; # Accept as many connections as possible, after nginx gets notification about a new connection. multi_accept on; >http < # Caches information about open FDs, freqently accessed files. open_file_cache max=200000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on; # Disable access log altogether. access_log off; # Sendfile copies data between one FD and other from within the kernel. sendfile on; # Causes nginx to attempt to send its HTTP response head in one packet, instead of using partial frames. tcp_nopush on; # Don't buffer data-sends (disable Nagle algorithm). tcp_nodelay on; # Timeout for keep-alive connections. Server will close connections after this time. keepalive_timeout 30; # Number of requests a client can make over the keep-alive connection. keepalive_requests 1000; # Allow the server to close the connection after a client stops responding. reset_timedout_connection on; # Send the client a "request timed out" if the body is not loaded by this time. client_body_timeout 10; # If the client stops reading data, free up the stale client connection after this much time. send_timeout 2; # Compression. gzip on; gzip_min_length 10240; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml; gzip_disable "msie6"; >
NGINX : Keep alive requests to static content ok — Keep alive requests to php-fpm requests hang until keepalive_timeout is reached
By default, a FastCGI server will close a connection right after sending the response. When set to the value on, nginx will instruct a FastCGI server to keep connections open. This in particular is necessary for keepalive connections to FastCGI servers to function.
Enables keep-alive connections for the upstream.
Num specifies the max number of connections to keep open before, if the max is reached it will close the least recently used connections.
Single treats everything as a single host. With this flag connections to different backends are treated as equal.
Both are valid for Nginx 1.1.4 or newer
Related videos on Youtube
محمّد محسن احمدی
Updated on September 18, 2022