Aug 8, 2011
tom

What is wrong in my php-fpm configuration?

Question

I have a 64-bit server but only 256MB of RAM. So, I moved to nginx server with fast-cgi to connect to PHP. I have PHP 5.3.6 running.

The issue is that after every two or three days when I try to access any PHP page then I get server internal error. The only way around is to restart php-fpm manually. This means I should have set some wrong parameters which is causing it to choke. Below I have listed the relevant configs.

/etc/php-fpm.conf :-

include=/etc/php-fpm.d/*.conf
log_level = error
;emergency_restart_threshold = 0
;emergency_restart_interval = 0
;process_control_timeout = 0

/etc/php-fpm.d/www.conf :-

[www]
pm = dynamic
pm.max_children = 10
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 5
pm.max_requests = 500

/etc/nginx/php.conf :-

location ~ .php {
        fastcgi_param  QUERY_STRING       $query_string;
        fastcgi_param  REQUEST_METHOD     $request_method;
        fastcgi_param  CONTENT_TYPE       $content_type;
        fastcgi_param  CONTENT_LENGTH     $content_length;        fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
        fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
        fastcgi_param  REQUEST_URI        $request_uri;
        fastcgi_param  DOCUMENT_URI       $document_uri;
        fastcgi_param  DOCUMENT_ROOT      $document_root;
        fastcgi_param  SERVER_PROTOCOL    $server_protocol;        fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
        fastcgi_param  SERVER_SOFTWARE    nginx;        fastcgi_param  REMOTE_ADDR        $remote_addr;
        fastcgi_param  REMOTE_PORT        $remote_port;
        fastcgi_param  SERVER_ADDR        $server_addr;
        fastcgi_param  SERVER_PORT        $server_port;
        fastcgi_param  SERVER_NAME        $server_name;        fastcgi_pass unix:---some-location---;
}

Update 1

And I have four nginx processes running. On an average each php-fpm process takes 35MB of RAM (Virtual memory size 320MB each). I also have a MySql process running.

Update 2

I forgot to paste the logs.

php-fpm error log :-

WARNING: [pool www] seems busy (you may need to increase start_servers, or min/max_spare_servers), spawning 8 children, there are 1 idle, and 7 total children
WARNING: [pool www] server reached max_children setting (10), consider raising it
NOTICE: Terminating ...

php-fpm www.error log :-

PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 122880 bytes) in /home/webadmin/blog.applegrew.com/html/wordpress/wp-content/plugins/jetpack/class.jetpack-signature.php on line 137
PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 122880 bytes) in /home/webadmin/blog.applegrew.com/html/wordpress/wp-content/plugins/jetpack/class.jetpack-signature.php on line 137
PHP Fatal error:  Allowed memory size of 33554432 bytes exhausted (tried to allocate 122880 bytes) in /home/webadmin/blog.applegrew.com/html/wordpress/wp-content/plugins/jetpack/class.jetpack-signature.php on line 137

Answer

An off-hand recommendation would be to lower your set values – probably cut them in half.

You have: pm.max_children = 10
If you say 35MB/process = 350MB; on a 256MB box that means either a lot of swapping or you run out of memory – neither is good.

I’d say take at least 100MB for other processes, maybe even 150MB to be safe, and then divide that number by 35MB to get your max_children. Keep all other numbers in line:

pm = dynamic
pm.max_children = 4
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 2
pm.max_requests = 500

Stop PHP-FPM and run free to get an idea of your available memory – divide by your 35MB to get your max_children.

Depending on how much memory MySQL takes, you might have to drop max_children to 3.

I do find that PHP-FPM processes share a lot of memory, do a quick experiment to determine how much is really used. Stop PHP-FPM and run free. Start PHP-FPM visit a few common pages (necessary since memory increases depending on the pages loaded), and check the total memory used, again using free – divide the difference by the number of processes. It isn’t a perfect system, but I do find it to be fairly accurate (sometimes the data column in top isn’t bad either).

Related posts:

  1. Nginx + php-fpm VS Nginx as a reverse proxy for Apache
  2. Nginx PHP mbstring
  3. PHP Session File Stored in Temp Directory – Apache
  4. How do I rename a mysql table in php?
  5. Apache with PHP configured as FastCGI and scripts without suffix

Leave a comment