Currently, Apache and php-fpm are the primary tools used on Linux systems to parse and run PHP web applications. php-fpm supports only multi-process mode, while Apache supports both multi-process and multi-threaded modes. However, in the vast majority of environments, the multi-process approach is used, so this article will focus solely on that.
In practice, a single instance can handle up to around 200-300 processes; exceeding 500 often leads to errors.
Each process consumes approximately 5M-15M of memory. Calculating at an average of 10M per process, 500 processes would only use about 5G of RAM. Since many high-performance servers now come with 64G or even 128G of memory, a single instance cannot fully utilize these memory resources.
I haven’t deployed many multi-instance environments in recent years because they aren’t necessary unless traffic is quite high.
The last time I configured multiple instances was for a Discuz forum with around 1 million PVs, which proved very effective. The current project is a static site with tens of millions of PVs, where requests mainly involve click counting. Adjusting the number of processes between 300 and 500 still occasionally causes crashes. Although the machine configuration is sufficient, stability remains an issue.
This guide does not cover LNMP or LNAMP environment configurations but focuses on setting up multiple instances based on an existing LNMP environment. Since I am using an LNAMP environment, I compiled an additional copy of PHP to /usr/local/php-fpm/, with configuration files located in /etc/php-fpm/, and took notes based on this setup.
First, modify three values:
1. Run php-fpm in ‘static’ mode, meaning a fixed number of processes.
2. Create 100 worker processes for each instance. (Avoid too many to prevent instability)
3. Exit each process after handling 200 requests. (To avoid PHP memory leaks, i.e., memory usage increasing over time)
sed -i ‘s#pm.max_children = 5#pm.max_children = 100#’ /etc/php-fpm/php-fpm.conf
sed -i ‘s#;pm.max_requests = 500#pm.max_requests = 200#’ /etc/php-fpm/php-fpm.conf
Below are the commands to copy php-fpm.conf and the php-fpm service management script.
cp php-fpm.conf php-fpm-1.conf
sed -i ‘s#listen = 127.0.0.1:9000#listen = 127.0.0.1:9001#’ php-fpm-1.conf
sed -i ‘s#[www]#[php-fpm-pool-1]#’ php-fpm-1.conf
sed -i ‘s#pid = run/php-fpm.pid#pid = run/php-fpm-1.pid#’ php-fpm-1.conf
cd /etc/init.d/
cp php-fpm php-fpm-1
sed -i ‘s#/etc/php-fpm/php-fpm.conf#/etc/php-fpm/php-fpm-1.conf#’ php-fpm-1
sed -i ‘s#/var/run/php-fpm.pid#/var/run/php-fpm-1.pid#’ php-fpm-1
service php-fpm-1 restart
After executing the above commands, you have copied a php-fpm instance. Both the service name and configuration file name are now php-fpm-1.
To create more copies, replace ‘-1’ with ‘-2’ in the above commands, increment the listen port accordingly, and execute them again.
Next, create a file named restart_php_fpm.sh with the following content:
service php-fpm-2 restart
service php-fpm-3 restart
… …
This script can be used to start and restart all php-fpm instances. To stop them, use the command killall php-fpm.
Then, configure Nginx.
Add the following in the http section:
server 127.0.0.1:9001;
server 127.0.0.1:9002;
server 127.0.0.1:9003;
server 127.0.0.1:9004;
server 127.0.0.1:9005;
}
Modify the server section:
fastcgi_pass php-fpm-pool;
fastcgi_index index.php;
include fastcgi.conf;
}
Configuration complete.
Effectively, multiple instances are equivalent to load balancing across multiple machines. However, I personally prefer configuring multiple instances on a single server (when accumulating equal resources), as it is much easier to configure, maintain, and use on one machine.