Nginx + php-fpm - Each php-fpm process 70-100% cpu when running

Solution 1:

A couple of things to consider (apologies in advance if you have already considered these): First of all, make sure to optimize your nginx config and invoke php-fpm only when absolutely necessary. The last thing you want to do is let php handle things like static HTML pages (which it will happily do).

Secondly, since you're using php-fpm, I suggest to be more aggressive with how long php-fpm's children are allowed to live. You need to find the sweet spot between shortly lived threads/children and stability. The php-fpm defaults are way too generous for any production system, IMHO. The longer a worker is allowed to serve requests, the more unstable it will get. There's also a higher risk of memory leaks, and if this framework you refer to has bugs like infinite loops, which may be causing you grief with CPU load, this shouldn't hurt.

I'd reduce the number for pm.max_requests for your production pools. I think the default is 200. I'd start from 50 and see where that takes you.

Failing/complementary to that, you could also try these global options (AFAIK they are all disabled by default):

emergency_restart_threshold 3
emergency_restart_interval 1m
process_control_timeout 5s

What does this mean? If 3 PHP-FPM child processes exit with SIGSEGV or SIGBUS (i.e. crash) within 1 minute then PHP-FPM is supposed to restart automatically. The child processes waits 5s for a reaction on signals from master.

Here's a nice overview of all the config options I mentioned here, as well as others: http://myjeeva.com/php-fpm-configuration-101.html

Hope these tips help you! Remember to tweak and observe, unfortunately there doesn't seem to be a rule of thumb for all this, as you observed, there are too many variables that affect PHP's behaviour and stability.

Finally, the CPU limiting facility you inquired about is documented here, but I'd only resort to it if you exhaust every other option. If you do choose this path, I'd definitely watch out for possible interactions between PHP-FPM tweaks and your limits.conf configuration. At that point etckeeper may be a lifesaver! :)

Good luck!

Rouben

Solution 2:

You are running opcode caching, right?

It used to be APC that was the go-to here, but it's been a buggy piece of for quite a while, and has been superseded by Zend Opcache, which is now part of PHP since 5.5, and has a backport in PECL for 5.3 and 5.4.