Thursday, March 8, 2018

NGINX and PHP-FPM

Scenario

Server with the following technical specs:
  • CPU: 4 @ 2.7GHZ
  • RAM: 8GB

Checking Nginx Parameter

Key areas to inspect when looking at Nginx for a PHP-FPM environment consist of worker_connections and worker_processes

Worker Connections

Sets the maximum number of simultaneous connections that can be opened by a worker process. This is often set to the number of CPU cores.

Worker Processes

Sets the maximum number of simultaneous connections that can be opened by a worker process.

PHP-FPM

MaxChildren

To optimize PHP-FPM it is largely depends on the application itself. However a standard rule that would satisfy a broad subset of use cases would be:

pm.max_children = (Total RAM - Memory used for Linux, DB, etc.) / Average php process size

First, we need to install ps_mem to check the memory usage.

CentOS 
yum install ps_mem -y

Ubuntu
wget http://www.pixelbeat.org/scripts/ps_mem.py mv ps_mem.py /usr/local/sbin/ chmod 755 /usr/local/sbin/ps_mem.py
then run command
ps_mem.py


Here is the result:


the output should give you something like this (refer to the picture shown as above):
 776.6 MiB + 49.4 MiB =   826.1 MiB    php-fpm (105)

This means php-fpm is using in total 826.1 MiB with 105 Processes. After converting the value in Megabyte, we will divide it by the number of processes. This will tell us: How much each child process (105) is consuming.

826.1 MiB/105 Processes =  7.86 MiB

7.86MB memory / Processes

We can now calculate the number of process php-fpm can calculate via this simple formula:

max_children = (Total Number of Memory - 1000MB) / FPM Memory per Process

We reserved 1000MB for other process like mysql, nginx, etc.

max_children = (4000 MB - 1000 MB) / 7.86

max_children = 381.67


Quick Setup

At a most base level this seems to be the ideal setup based on peer review:
  • nginx (<=1.9.0)
  • zendopcache > apc (deprecated)
  • php-fpm (fastcgi)
Note: It is also important to highlight that single core php-fpm instances will not gain much of a performance improvement. PHP-FPM benefits proportionately to the number of cpu cores available. While a dual core would yield a performance gain. A recommended number would be at least 4 cores.


Detailed Setup

In the /etc/php5/fpm/pool.d/www.conf file:

[www]
user = www-data
group = www-data
chdir = /
listen = 127.0.0.1:9000
pm = dynamic            (ondemand might be better for memory usage)
pm.max_children         (total RAM - (DB etc) / process size)
pm.start_servers        (1/4 of cpu cores)
pm.min_spare_servers    (1/2 of cpu cores)
pm.max_spare_servers    (total of cpur cores)
pm.max_requests         (high to prevent server respwan)
                        (tip: set really low to find memory leaks)
In the /etc/php5/fpm/conf.d/local.ini file:

memory_limit = 324M (WxT needs at minimum 256MB)
 
According to our scenario sample then it will give result as below
pm = ondemand            
pm.max_children         (382)
pm.start_servers        (1)
pm.min_spare_servers    (2)
pm.max_spare_servers    (4)
pm.max_requests         (1000)
                       
  
Then just execute the following commands:
nginx -s reload




Other Topics: