How to make nginx proxy php to fastcgi evenly on all cores.
Top shows usage of only 2 cores when I try to stress test configuration.
Cpu0 : 62.6%us, 14.9%sy, 0.0%ni, 18.5%id, 0.3%wa, 0.0%hi, 3.6%si, 0.0%st
Cpu1 : 57.1%us, 11.0%sy, 0.0%ni, 31.2%id, 0.0%wa, 0.0%hi, 0.7%si, 0.0%st
Cpu2 : 1.3%us, 0.7%sy, 0.0%ni, 97.0%id, 0.0%wa, 0.0%hi, 1.0%si, 0.0%st
Cpu3 : 2.0%us, 1.7%sy, 0.0%ni, 95.7%id, 0.0%wa, 0.0%hi, 0.7%si, 0.0%st
I got
worker_processes 20;
Set in nginx.conf
Start fast cgi with
spawn-fcgi -s /tmp/php.sock -f /usr/sbin/php -u nobody -g nogroup -U nobody -G nogroup -C 160 -P /var/run/spawn-fcgi.pid
And proxy block in nginx.conf that calls fast cgi is
location ~ \.php$
{
include fastcgi_params;
fastcgi_pass unix:/tmp/php.sock;
fastcgi_param SCRIPT_FILENAME /var/www/$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
}
Setting your nginx worker processes to 20 is unnecessary. With four CPU cores, there is no reason to set it higher than 4. Even if you had more CPU cores, you probably wouldn't benefit from setting this higher.
In addition to setting your nginx processes too high, you maybe be seting your fastcgi processes too high. 160 is a lot. Unless your PHP code spends a lot of time waiting on slow resources, I doubt you really want to handle 160 FastCGI requests at once. Since you only have 4 cores, this will make each request take longer to complete.
I'm unsure why you think your CPU isn't being utililzed effectively. Looking at your top output, the two cores that are busiest were still idle 20 and 30 percent of the time. This could mean that PHP was only having to pass requests on to two FastCGI processes at once to keep up with the load, or it could mean that it handled as many as 160 concurrent requests but that they didn't need much CPU time (e.g. they were waiting on the network or disk). Either way, if the work had been more evenly spread out across all four cores it wouldn't have completed any faster.
Although I wouldn't recommend it, you can force processes to run on specific cores using
taskset
. The basic syntax istasket -c $CPU_LIST -p $PID
. E.G. To ensure that process 17325 will only run on the first CPU core, you would runcpuset -c 0 -p 17325
. This sort of functionality isn't integrated into spawn-fcgi, and since PHP processes will keep coming and going as they hit PHP_FCGI_MAX_REQUESTS (it defaults to 500) and are replaced, balancing them across cores yourself would be tricky. It's better to let the linux scheduler handle this as needed.