I. What is FastCGI
FastCGI is a scalable, high-speed interface for communication between HTTP servers and dynamic scripting languages. Most popular HTTP servers support FastCGI, including Apache, Nginx, and lighttpd. At the same time, FastCGI is also supported by many scripting languages, including PHP.
FastCGI evolved and improved from CGI. The main drawback of the traditional CGI interface is poor performance, because every time the HTTP server encounters a dynamic program it needs to restart the script parser to perform parsing, and then the result is returned to the HTTP server. When handling high-concurrency access, this is almost unusable. Additionally, the traditional CGI interface method has poor security and is now rarely used.
The FastCGI interface method uses a C/S architecture, allowing the HTTP server and the script parsing server to be separated, while starting one or more script parsing daemon processes on the script parsing server. Whenever the HTTP server encounters a dynamic program, it can directly deliver it to the FastCGI process for execution, and then return the obtained result to the browser. This method allows the HTTP server to focus on handling static requests or returning the results of the dynamic script server to the client, which greatly improves the performance of the entire application system.
II. Nginx+FastCGI Operating Principle
Nginx does not support direct calling or parsing of external programs. All external programs (including PHP) must be called through the FastCGI interface. The FastCGI interface is a socket on Linux (this socket can be a file socket or an IP socket). To call CGI programs, a FastCGI wrapper is also needed (a wrapper can be understood as a program used to start another program). This wrapper is bound to a fixed socket, such as a port or file socket. When Nginx sends a CGI request to this socket, through the FastCGI interface, the wrapper accepts the request and then spawns a new thread, which calls the interpreter or external program to process the script and read the returned data. Then, the wrapper passes the returned data back through the FastCGI interface along the fixed socket to Nginx. Finally, Nginx sends the returned data to the client. This is the entire operation process of Nginx+FastCGI. The detailed process is shown in Figure 1.
Figure 1. Nginx+FastCGI Operating Principle
III. spawn-fcgi and PHP-FPM
As introduced earlier, the FastCGI interface method starts one or more daemon processes on the script parsing server to parse dynamic scripts. These processes are FastCGI process managers, also known as FastCGI engines. spawn-fcgi and PHP-FPM are two FastCGI process managers that support PHP.
Below is a brief introduction to the similarities and differences between spawn-fcgi and PHP-FPM.
spawn-fcgi is part of the HTTP server lighttpd and has now become an independent project. It is generally used with lighttpd to support PHP, but lighttpd’s spawn-fcgi can experience memory leaks and even automatically restart the FastCGI process under high-concurrency access.
Nginx is a lightweight HTTP server and must rely on third-party FastCGI processors to parse PHP. Therefore, the Nginx+spawn-fcgi combination can also achieve PHP parsing, but this will not be discussed in detail here.
PHP-FPM is also a third-party FastCGI process manager. It was developed as a patch for PHP and needs to be compiled together with the PHP source code during installation. That is to say, PHP-FPM is compiled into the PHP kernel, so it performs better in terms of processing performance. At the same time, it handles high concurrency much better than the spawn-fcgi engine. Therefore, the Nginx+PHP/PHP-FPM combination is recommended for PHP parsing.
The main advantage of FastCGI is that it separates the dynamic language from the HTTP Server. Therefore, Nginx and PHP/PHP-FPM are often deployed on different servers to share the load on the front-end Nginx server, allowing Nginx to focus on handling static requests and forwarding dynamic requests, while the PHP/PHP-FPM server focuses on parsing PHP dynamic requests.
IV. PHP and PHP-FPM Installation and Optimization
1. Download the installation package
Download the PHP source package from the official website at www.php.net. The stable version downloaded here is php-5.2.13.tar.gz.
Download the corresponding PHP-FPM source package from http://php-fpm.org/downloads/. The version downloaded here is php-5.2.13-fpm-0.5.13.diff.gz.
Note: when downloading software package versions, try to keep the PHP and PHP-FPM versions consistent. If the versions differ too much, compatibility issues may arise.
2. Configure the installation environment
Installing PHP requires the following software packages. If they are not installed, please install them yourself.
- gcc gcc-c++ libxml2 libxml2-devel autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel
Due to the variability of different Linux system versions, readers can also install the corresponding software libraries based on error messages during the PHP installation process.
3. Start compiling and installing PHP and PHP-FPM
Compiling and installing PHP and PHP-FPM is very simple. The installation process is as follows:
- [root@localhost local]#tar zxvf php-5.2.13.tar.gz
- [root@localhost local]#gzip -cd php-5.2.13-fpm-0.5.13.diff.gz | patch -d php-5.2.13 -p1
- [root@localhost local]#cd php-5.2.13
- [root@localhost php-5.2.13]#./configure –prefix=/usr/local/php –enable-fastcgi –enable-fpm
- [root@localhost php-5.2.13]#make
- [root@localhost php-5.2.13]#make install
- [root@localhost php-5.2.13]cp php.ini-dist /usr/local/php/lib/php.ini
In step two, PHP-FPM is added as a patch into the PHP source code.
In the “./configure” compilation options, PHP is specified to be installed under /usr/local. “–enable-fastcgi” enables FastCGI support for PHP, and “–enable-fpm” activates fpm support for FastCGI mode.
Many compilation options can be added when compiling PHP, but here, to introduce PHP’s FastCGI functionality, no additional compilation options are included.
4. Configure and Optimize PHP-FPM
PHP’s global configuration file is php.ini. In the steps above, this file has already been copied to /usr/local/php/lib/php.ini. You can configure php.ini accordingly based on each application’s requirements.
Below, we focus on introducing the configuration file of the PHP-FPM engine.
According to the installation path specified above, the default configuration file for PHP-FPM is /usr/local/php/etc/php-fpm.conf.
php-fpm.conf is an XML-format plain text file, and its content is easy to understand. Here, we focus on several important configuration tags:
The listen_address tag configures the IP address and port that the fastcgi process listens on. The default is 127.0.0.1:9000.
The display_errors tag is used to set whether to display PHP error messages. The default is 0, which does not display error messages. Setting it to 1 will display PHP error messages.
The user and group tags are used to set the user and user group for running the FastCGI process. Note that the user and user group specified here must match the user and user group specified in the Nginx configuration file.
The max_children tag is used to set the number of FastCGI processes. According to official recommendations, servers with less than 2GB of memory can open only 64 processes, while servers with more than 4GB of memory can open 200 processes.
The request_terminate_timeout tag is used to set the time for FastCGI to execute a script. The default is 0s, which means unlimited execution time. It can be modified according to the situation.
The rlimit_files tag is used to set the limit on open file descriptors for PHP-FPM. The default value is 1024. The value of this tag must be associated with the number of open files in the Linux kernel. For example, to set this value to 65535, you must execute ‘ulimit -HSn 65536’ on the Linux command line.
The max_requests tag indicates how many requests each child process will handle before being closed. The default setting is 500.
The allowed_clients tag is used to set the IP addresses allowed to access the FastCGI process parser. If no IP address is specified here, the PHP parsing requests forwarded by Nginx will not be accepted.
5. Managing FastCGI Processes
After configuring php-fpm, you can start the FastCGI process. There are two ways to start the fastcgi process:
- /usr/local/php/bin/php-cgi –fpm
- or
- /usr/local/php/sbin/php-fpm start
It is recommended to use the second method to start the FastCGI process.
/usr/local/php/sbin/php-fpm has other parameters as well, specifically: start|stop|quit|restart|reload|logrotate.
The meaning of each startup parameter is as follows:
- ? start, starts PHP’s FastCGI process.
- ? stop, forcefully terminates PHP’s FastCGI process.
- ? quit, gracefully terminates PHP’s FastCGI process.
- ? restart, restarts PHP’s FastCGI process.
- ? reload, reloads PHP’s php.ini.
- ? logrotate, re-enables the log file.
reload is a very important parameter. It allows reloading modified php.ini without interrupting PHP’s FastCGI process. Therefore, php-fpm can smoothly change PHP settings in FastCGI mode.
After the FastCGI process starts, the IP address and port it listens on also start immediately. You can view the relevant information using ps and netstat.
- [root@localhost php]# netstat -antl|grep 9000
- tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN
- [root@localhost php]# ps -ef|grep php-cgi
- root 3567 1 0 17:06 ? 00:00:00 /usr/local/php/bin/php-cgi –fpm –fpm-config /usr/local/php/etc/php-fpm.conf
- nobody 3568 3567 0 17:06 ? 00:00:00 /usr/local/php/bin/php-cgi –fpm –fpm-config /usr/local/php/etc/php-fpm.conf
- nobody 3569 3567 0 17:06 ? 00:00:00 /usr/local/php/bin/php-cgi –fpm –fpm-config /usr/local/php/etc/php-fpm.conf
- nobody 3570 3567 0 17:06 ? 00:00:00 /usr/local/php/bin/php-cgi –fpm –fpm-config /usr/local/php/etc/php-fpm.conf
- nobody 3571 3567 0 17:06 ? 00:00:00 /usr/local/php/bin/php-cgi –fpm –fpm-config /usr/local/php/etc/php-fpm.conf
- nobody 3572 3567 0 17:06 ? 00:00:00 /usr/local/php/bin/php-cgi –fpm –fpm-config /usr/local/php/etc/php-fpm.conf
- root 3583 3524 0 17:09 pts/1 00:00:00 grep php-cgi
V. Configuring Nginx to Support PHP
Nginx installation is particularly simple and has already been introduced in detail earlier, so it will not be repeated here. Below, we focus on how Nginx uses the php-fpm FastCGI process to parse and handle PHP.
Since Nginx itself does not parse PHP, to enable Nginx to support PHP, requests for PHP pages are actually handed over to the IP address and port that the FastCGI process listens on. If php-fpm is treated as a dynamic application server, then Nginx is essentially a reverse proxy server. Nginx implements PHP parsing through its reverse proxy functionality, which is the principle of Nginx implementing PHP dynamic parsing.
Here, assuming the Nginx installation directory is /usr/local, the path to the Nginx configuration file is /usr/local/nginx/conf/nginx.conf. Below is a virtual host configuration example for supporting PHP parsing under Nginx.
- server {
- include port.conf;
- server_name www.ixdba.net ixdba.net;
- location / {
- index index.html index.php;
- root /web/www/www.ixdba.net;
- }
- location ~ /.php$ {
- root html;
- fastcgi_pass 127.0.0.1:9000;
- fastcgi_index index.php;
- fastcgi_param SCRIPT_FILENAME html$fastcgi_script_name;
- include fastcgi_params;
- }
- }
Through the location directive, all files with the php suffix are handed over to 127.0.0.1:9000 for processing, and the IP address and port here are the IP address and port that the FastCGI process listens on.
The fastcgi_param directive specifies the main directory where PHP dynamic programs are placed, which is the path specified before $fastcgi_script_name, here it is the /usr/local/nginx/html directory. It is recommended to keep this directory consistent with the root directory specified by the Nginx virtual host, although it can also be different.
The fastcgi_params file is a parameter configuration file for the FastCGI process. After installing Nginx, such a file is generated by default. Here, the FastCGI parameter configuration file is included through the include directive.
Next, start the nginx service.
/usr/local/nginx/sbin/nginx
At this point, Nginx+PHP has been configured.
VI. Testing Nginx’s PHP Parsing Functionality
Here, create a phpinfo.php file in the /usr/local/nginx/html directory with the following content:
Then access http://www.ixdba.net/index.html through a browser. The browser should display “Welcome to Nginx!” by default, indicating that Nginx is running normally.
Next, access http://www.ixdba.net/phpinfo.php in the browser. If PHP can parse normally, the PHP installation configuration and feature list statistics information will appear.
VII. Practical Example: Optimizing FastCGI Parameters in Nginx
After configuring Nginx+FastCGI, to ensure the high-speed and stable operation of the PHP environment under Nginx, some FastCGI optimization directives need to be added. Below is an optimization example. Add the following code to the HTTP level in the Nginx main configuration file.
- fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m;
- fastcgi_connect_timeout 300;
- fastcgi_send_timeout 300;
- fastcgi_read_timeout 300;
- fastcgi_buffer_size 64k;
- fastcgi_buffers 4 64k;
- fastcgi_busy_buffers_size 128k;
- fastcgi_temp_file_write_size 128k;
- fastcgi_cache TEST;
- fastcgi_cache_valid 200 302 1h;
- fastcgi_cache_valid 301 1d;
- fastcgi_cache_valid any 1m;
Below is an introduction to the meaning of the above code.
The first line of code specifies a file path, directory structure level, keyword area storage time, and inactive deletion time for the FastCGI cache.
fastcgi_connect_timeout specifies the timeout for connecting to the backend FastCGI.
fastcgi_send_timeout specifies the timeout for sending requests to FastCGI. This value is the timeout for sending requests to FastCGI after the two-way handshake is completed.
fastcgi_read_timeout specifies the timeout for receiving FastCGI responses. This value is the timeout for receiving FastCGI responses after the two-way handshake is completed.
fastcgi_buffer_size is used to specify how large a buffer is needed to read the first part of the FastCGI response. This value indicates that one 64KB buffer will be used to read the first part of the response (response header). It can be set to the buffer size specified by the fastcgi_buffers option.
fastcgi_buffers specifies how many and how large local buffers are needed to buffer FastCGI response requests. If a PHP script generates a page size of 256KB, then 4 buffers of 64KB each will be allocated to cache it. If the page size is larger than 256KB, the portion exceeding 256KB will be cached to the path specified by fastcgi_temp. However, this is not a good approach because data processing speed in memory is faster than on disk. Generally, this value should be the median page size generated by PHP scripts on the site. If most scripts on the site generate pages of 256KB, you can set this value to “16 16k”, “4 64k”, etc.
The default value of fastcgi_busy_buffers_size is twice that of fastcgi_buffers.
fastcgi_temp_file_write_size indicates the data block size to use when writing cache files. The default value is twice that of fastcgi_buffers.
fastcgi_cache indicates that FastCGI caching is enabled and assigns it a name. Enabling caching is very useful as it can effectively reduce CPU load and prevent 502 errors. However, enabling caching can also cause many issues, so it should be considered on a case-by-case basis.
fastcgi_cache_valid and fastcgi are used to specify the cache time for response codes. The values in the example indicate that 200 and 302 responses are cached for one hour, 301 responses are cached for one day, and all other responses are cached for one minute.
This article is from “Technology Makes Dreams Come True” blog. Please be sure to retain this source http://ixdba.blog.51cto.com/2895551/806622
