Nginx & FastCGI buffering to slow clients, thousands of connections backup to fast-cgi/php processes
mushero
nginx-forum at nginx.us
Sun Dec 20 16:49:14 MSK 2009
I assume this has been covered before but despite lots of searching, cannot find it.
We run many nginx servers with fast-cgi for PHP, but here in China the connections can be slow or dynamic, so suddenly we have 1000 connections in 'write' status in Nginx. This should be no problem, but these seem to be backing up the fast-cgi processes, eventually running out and the whole system locks up from a users' perspective, with 502 errors since nginx can't find any more fast-cgi processes to talk with (they are all busy).
Errors we get are usually "upstream timed out (110: Connection timed out) while reading response header from upstream, client: 61.149.175.16, server: 121.13.44.145, request: "GET /...
In this scenario, we'd need 1000+ fast-cgi processes to handle all the open connections. We'd prefer to run 10-20 php connections, which can easily handle all the performance needs.
We thought, this is simple, just add more buffering so all the PHP output is in memory in Nginx, and it will close the connection to PHP and another user can use it. These are big servers, with 8-16 cores and 24GB+ RAM so we have plenty of power and memory. So we added bigger buffers to 64KB and added thousands of buffers, etc. but Nginx's memory size didn't really increase (very small at 30-50MB) and the problem didn't go away. And we have no buffering to disk messages in the logs.
So if the buffers are big enough and/or we have disks space, I am thinking nginx will ALWAYS buffer ALL the fastcgi data and the connection will close, so we should NEVER see fastcgi waiting for nginx to write data to a client - is this correct?
First, are these buffer settings per connection or for all connections ? I assume fastcgi_buffer_size is per connection. But if fastcgi_buffers is per connection, why have a buffer count, why not just say 32K, 64K, etc.? So I'm guessing this is the total buffers available to the server, in blocks of the buffer size, for example fastcgi_buffers 1024 64k gives me 64MB of total buffer space. If I have 100 connections, I can buffer about 600KB each, etc. before nginx starts buffering to files.
Without a fix we are running 1000 cgi processes and 1-2K nginx connections. This works but if we ever get real load, we'll have a 250 load average, like we used to see on loaded Apache systems. We need a way to use 10-20 PHP processes on a few thousand slow connections.
I assume we have buffering problems, but maybe there is a close or other issue that prevents the php from being re-used, but this works great when the connections are fast and the % of writers is small.
The fastcgi engine is php5-cgi; maybe we should use spawn-cgi from lighttpd.
Key configis are:
events {
worker_connections 4096;
use epoll;
multi_accept off;
}
http {
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 15;
tcp_nodelay on;
server {
listen 80;
server_name 120.136.43.145 abc.com.cn 127.0.0.1;
root /var/www/abc;
access_log /var/log/nginx/abc.com_access.log;
error_log /var/log/nginx/abc.com_error.log;
index index.html index.php index.htm;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_buffer_size 64k;
fastcgi_buffers 4096 64k;
fastcgi_param SCRIPT_FILENAME /var/www/abc$fastcgi_script_name;
include fastcgi_params;
}
}
Posted at Nginx Forum: http://forum.nginx.org/read.php?2,32120,32120#msg-32120
More information about the nginx
mailing list