PHP-FPM (FastCGI Process Manager) is an alternative
FastCGI
implementation with some additional features useful for websites of any
size, especially high-load websites. It makes it particularly easy to
run
PHP on
Nginx.
Included features – from original website :
- Adaptive process spawning
- Basic statistics
- Advanced process management with graceful stop/start
- Ability to start workers with different uid/gid/chroot/environment and different php.ini
- Stdout & stderr logging
- Emergency restart in case of accidental opcode cache destruction
- Accelerated upload support
- Support for a “slowlog”
- Enhancements to FastCGI, such as fastcgi_finish_request() – a special
function to finish request & flush all data while continuing to do
something time-consuming
..and much more..
Notice :
PHP-FPM is not designed with virtual hosting in mind (large amounts of pools) however it can be adapted for any usage model.
Let’s start with installation (Ubuntu/Debian) :
sudo apt-get update
sudo apt-get install php5-fpm
# check if everything is working
php5-fpm -v
You can also install other required
PHP packages :
sudo apt-get install php5-common
sudo apt-get install php5-curl
sudo apt-get install php5-mysqli
...
Notice :
This configuration is based on
this Nginx test server.
We can now continue to configure
PHP-FPM, but first try to make backup of your original
www.conf file :
sudo nano /etc/php5/fpm/pool.d/www.conf
# pool name
[www1]
# user of FPM processess
user = www-data
# group of FPM processess
group = www-data
# address on which FastCGI requests are accepted, this can also be unix socket. Mandatory for each pool
# please take in mind that they say that unix socket is bit faster than tcp but honestly i didn't notice it, what i noticed is that on unix socket i get bunch of errors..
listen = "127.0.0.1:9000"
# how process manager controll number of children. Option is mandatory
# static - child processes are fixed - pm.max_children
# ondemand - processes spawn on demand, opposite to dynamic where started processes on service started
# dynamic - processes are spawned as said depending on directives : max_children, start_servers, min_spare_servers, max_spare_servers
pm = dynamic
pm.max_children = 4096
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 128
# number of requests each child should execute before respawning.
pm.max_requests = 1024
# uri on which you can check your fpm status
pm.status_path = /php-status
# log file for slow requests
slowlog = /var/log/php-fpm.slow.log
listen.backlog = -1
After this done you can copy it and paste no more than 4 times, it’s
not good to have more than 4 pools because those configs are made for
heavy load web site (only one) :
[www1]
user = www-data
group = www-data
listen = "127.0.0.1:9000"
pm = dynamic
pm.max_children = 4096
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 128
pm.max_requests = 1024
pm.status_path = /php-status
slowlog = /var/log/php-fpm.slow.log
listen.backlog = -1
[www2]
user = www-data
group = www-data
listen = "127.0.0.1:9001"
pm = dynamic
pm.max_children = 4096
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 128
pm.max_requests = 1024
pm.status_path = /php-status
slowlog = /var/log/php-fpm.slow.log
listen.backlog = -1
[www3]
user = www-data
group = www-data
listen = "127.0.0.1:9002"
pm = dynamic
pm.max_children = 4096
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 128
pm.max_requests = 1024
pm.status_path = /php-status
slowlog = /var/log/php-fpm.slow.log
listen.backlog = -1
[www4]
user = www-data
group = www-data
listen = "127.0.0.1:9003"
pm = dynamic
pm.max_children = 4096
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 128
pm.max_requests = 1024
pm.status_path = /php-status
slowlog = /var/log/php-fpm.slow.log
listen.backlog = -1
What i noticed, when i have only one pool it always brakes when i
have heavy load at the some moments but after few seconds it’s working
normally again, so i added more than one pool but as i said above, max 4
pools.
After we added pools now we need to setup upstreams in
Nginx config with
sudo nano /etc/nginx/nginx.conf :
upstream php {
server 127.0.0.1:9100;
server 127.0.0.1:9001;
server 127.0.0.1:9002;
server 127.0.0.1:9003;
}
Those are our upstream
FastCGI servers which will be used as round robin for processing requests.
On
Nginx vhost side, we will need change param for passing requests to upstream servers (pools) :
location ~ \.php$ {
fastcgi_pass php;
}
Now restart
Nginx and
PHP-FPM and you are done.
Please take in mind that this guide is made for our test server and
you will maybe need to play with those numbers, depending on your CPU
and memory you can lower down
max_children and
max_spare_servers.
Happy hacking!