PHP-FPM
PHP-FPM (FastCGI Process Manager) is an alternative PHP FastCGI implementation, which allows to run PHP as a separate process and has some additional useful features:
- 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 (video converting, stats processing, etc.)
FastCGI is a binary protocol for interfacing interactive programs with a web server. FastCGI is a variation on the earlier Common Gateway Interface (CGI); FastCGI's main aim is to reduce the overhead associated with interfacing the web server and CGI programs, allowing a server to handle more web page requests at once.
CGI is an interface which tells the webserver how to pass data back and forth to and from an application. More specifically, it describes how request information is passed in environment variables (such as request type, remote IP address), how the reqeust body is passed in via standard input, and how the response is passed out via standard output.
PHP-FPM uses “persistent processes”. Rather than killing and re-creating a process on each request, FPM will re-use processes.
Install PHP-FPM
sudo apt-get install -y php5-fpm
sudo service php5-fpm start
Configure PHP-FPM
FPM configuration includes php.ini
file, conf.d
directory, php-fpm.conf
global configuration and pool.d
directory with FPM’s resource pools configuration (default www.conf
).
drwxr-xr-x 4 root root 4.0K May 31 00:26 .
drwxr-xr-x 4 root root 4.0K May 31 00:26 ..
drwxr-xr-x 2 root root 4.0K May 31 00:26 conf.d
-rw-r--r-- 1 root root 4.5K Apr 17 11:57 php-fpm.conf
-rw-r--r-- 1 root root 69K May 31 00:26 php.ini
drwxr-xr-x 2 root root 4.0K May 31 00:26 pool.d
Global Configuration
Global configuration is /etc/php5/php-fpm.conf
error_log = /var/log/php5-fpm.log
error loglog_level = notice
the log level of reporting to the error logemergency_restart_threshold = 0
number of child processes to exit with errors hat will trigger a graceful restart of FPM.emergency_restart_interval=0
interval of time used to determine when a graceful restart will be initiateddaemonize = yes
run PHP-FPM as a daemon, in the background.include=/etc/php5/fpm/pool.d/*.conf
include all confguration files
Resource Pools
PHP-FPM can have separate resource “pools”. Each pool represents an “instance” of PHP-FPM, which can be used to send PHP requests.
Separate resource pool configurration has some advantages:
- Each resource pool listens on its own socket. They do not share memory space, a boon for security.
- Each resource pool can run as a different user and group. This allows for security between files associated with each resource pool.
- Each resource pool can have different styles of process management, allowing to give more or less power to each pool.
listen = /var/run/php5-fpm.sock
by default, PHP-FPM listens on a Unix socket.
A “socket” is merely a means of communication. Unix sockets are faux-files which work to pass data back and forth. A TCP socket is the combination of an IP address and a port, used for the same purpose. A Unix socket is a little faster than a TCP socket, but it is limited in use to the local file system.
If PHP-FPM process will always live on the same server as web server, then it can have default Unix socket, but if PHP-FPM is communicating to a remote server, then it needs to use a TCP socket.
Change socket to a TCP listen = 127.0.0.1:9000
This listens on the loopback network interface (localhost) on port 9000
. If PHP-FPM needto listen for remote connections it needs to be binded to the other network interfaces:
# Binding to network 192.168.12.*
listen = 192.168.12.12:9000
The three most important settings as far as performance goes are:
pm
setting determines how the process manager will control the number of child processes. You can choose static
, ondemand
, or dynamic
.
ondemand
is used for lower traffic websites.Processes do not sit there doing nothing if they're not going to be used, so they can only be spawned when they are requested.- If a webserver consistently has traffic, it's better to switch to
dynamic
. Dynamic settings will ensure PHP-FPM have x number of processes ready to work.pm.start_servers = 5
is set to 10% or so of yourmax_children
.
pm.min_spare_servers = 3
This ensures PHP-FPM always has 3 spare processes. So if it has 35 busy processes, it'll have 38 PHP-FPM processes, with 3 ready to handle incoming requests.
pm.max_spare_servers = 6
If a webserver has a spike in traffic that requires spawning more than 6 processes, this number will get rid of those processes to get back to 6 once they're not needed anymore.
Keep in mind pm.start_servers
, pm.min_spare_servers
and pm.max_spare_servers
are only used for dynamic.
pm.max_children
option is mandatory no matter what pm mode is choosen. It is very important, because it controls the maximum number of FPM processes that the system can run at the same time.
It's required to pick a reasonable number depending on how much memory is on the server.
A good way of figuring out this number is to think in terms of available memory. If you have 2GB: you assume Nginx + other processes will use at most 300MB, and you assume 20MB/process, you could do ( 2000MB - 300MB ) / 20 MB = roughly 90. ( MAX_MEMORY - 300MB ) / 20 MB.
pm.max_children = 90
pm.max_requests
setting determines how many requests each child process should handle before respawning. Useful setting to avoid memory runoff from 3rd party libraries and such.
Sources: