What is the relationship between CGI, FastCGI and PHP-FPM?

When building a LAMP/LNMP server, you will often encounter the concepts of PHP-FPM, FastCGI and CGI. If you have a little knowledge of them, it is difficult to build a high-performance server. Next, we will graphically explain the relationship between these concepts.
Foundation
In the entire website architecture, Web Server (such as Apache) is just a content distributor. For example, if the client requests index.html, the Web Server will find the file in the file system and send it to the browser, where static data is distributed.
image

If the request is index.php, according to the configuration file, Web Server knows that this is not a static file and needs to find a PHP parser for processing, then he will simply process the request and hand it over to the PHP parser.
image
When the Web Server receives the index.php request, it will start the corresponding CGI program, here is the PHP parser. Next, the PHP parser will parse the php.ini file, initialize the execution environment, then process the request, and then return the processed result in the format specified by the CGI, exit the process, and the Web server will return the result to the browser. This is a complete dynamic PHP Web access process, and then these concepts will be introduced to understand a lot.


CGI: It is a protocol for data exchange between Web Server and Web Application.

FastCGI: Same as CGI, it is a communication protocol, but has some optimizations in terms of efficiency than CGI. Similarly, the SCGI protocol is similar to FastCGI.

 

PHP-CGI: It is the interface program of CGI protocol provided by PHP (Web Application) to Web Server. 


PHP-FPM: It is the interface program of FastCGI protocol provided by PHP (Web Application) to Web Server, and additionally provides relatively intelligent task management.


In WEB, Web Server generally refers to servers such as Apache, Nginx, IIS, Lighttpd, Tomcat, etc., and Web Application generally refers to applications such as PHP, Java, Asp.net, etc.


Module method
Before we understand CGI, let’s take a look at another method for Web server to transmit data: PHP Module loading method . Take Apache as an example. In the PHP Module mode, do you add these sentences to the Apache configuration file httpd.conf:

# Add the following 2 sentences
LoadModule php5_module D:/php/php5apache2_2.dll
AddType application/x-httpd-php .php
# Modify the following content
<IfModule dir_module>
    DirectoryIndex index.php index.html
</IfModule>
The above is the manual configuration after installing the php and apache environment under Windows. The source code installation under linux is roughly like this
Configured:
# ./configure --with-mysql=/usr/local --with-apache=/usr/local/apache --enable-track-vars

Therefore, in this way, their common essence is to use LoadModule to load php5_module, which is to run php as a submodule of apache . When accessing the php file through the web, apache will call php5_module to parse the php code.

So how does php5_module pass the data to the php parser to parse the php code? The answer is through sapi.


Let’s look at another picture to talk about the relationship between apache and php and sapi in detail:
image
From the above figure, we can see that sapi is such an intermediate process. SAPI provides an interface for communicating with the outside, which is a bit similar to sockets. , So that PHP can interact with other applications (apache, nginx, etc.). PHP provides many kinds of SAPI by default, the common ones are php5_module, CGI, FastCGI for apache and nginx, ISAPI for IIS, and CLI for Shell.

Therefore, the above apache call php execution process is as follows:

apache -> httpd -> php5_module -> sapi -> php
All right.


这种模式将php模块安装到apache中,所以每一次apache结束请求,都会产生一条进程,这个进程就完整的包括php的各种运算计算等操作。
在上图中,我们很清晰的可以看到,apache每接收一个请求,都会产生一个进程来连接php通过sapi来完成请求,可想而知,如果一旦用户过多,并发数过多,服务器就会承受不住了。

而且,把mod_php编进apache时,出问题时很难定位是php的问题还是apache的问题。


CGI
CGI(Common Gateway Interface)全称是“通用网关接口”,WEB 服务器与PHP应用进行“交谈”的一种工具,其程序须运行在网络服务器上。CGI可以用任何一种语言编写,只要这种语言具有标准输入、输出和环境变量。如php、perl、tcl等。

WEB服务器会传哪些数据给PHP解析器呢?URL、查询字符串、POST数据、HTTP header都会有。所以,CGI就是规定要传哪些数据,以什么样的格式传递给后方处理这个请求的协议。仔细想想,你在PHP代码中使用的用户从哪里来的。

也就是说,CGI就是专门用来和 web 服务器打交道的。web服务器收到用户请求,就会把请求提交给cgi程序(如php-cgi),cgi程序根据请求提交的参数作应处理(解析php),然后输出标准的html语句,返回给web服服务器,WEB服务器再返回给客户端,这就是普通cgi的工作原理。

CGI的好处就是完全独立于任何服务器,仅仅是做为中间分子。提供接口给apache和php。他们通过cgi搭线来完成数据传递。这样做的好处了尽量减少2个的关联,使他们2变得更独立。

但是CGI有个蛋疼的地方,就是每一次web请求都会有启动和退出过程,也就是最为人诟病的fork-and-execute模式,这样一在大规模并发下,就死翘翘了。


FastCGI简单介绍

从根本上来说,FastCGI是用来提高CGI程序性能的。类似于CGI,FastCGI也可以说是一种协议

FastCGI像是一个常驻(long-live)型的CGI,它可以一直执行着,只要激活后,不会每次都要花费时间去fork一次。它还支持分布式的运算, 即 FastCGI 程序可以在网站服务器以外的主机上执行,并且接受来自其它网站服务器来的请求。

FastCGI是语言无关的、可伸缩架构的CGI开放扩展,其主要行为是将CGI解释器进程保持在内存中,并因此获得较高的性能。众所周知,CGI解释器的反复加载是CGI性能低下的主要原因,如果CGI解释器保持在内存中,并接受FastCGI进程管理器调度,则可以提供良好的性能、伸缩性、Fail- Over特性等等。

FastCGI的工作原理

FastCGI接口方式采用C/S结构,可以将HTTP服务器和脚本解析服务器分开,同时在脚本解析服务器上启动一个或者多个脚本解析守护进程。当HTTP服务器每次遇到动态程序时,可以将其直接交付给FastCGI进程来执行,然后将得到的结果返回给浏览器。这种方式可以让HTTP服务器专一地处理静态请求,或者将动态脚本服务器的结果返回给客户端,这在很大程度上提高了整个应用系统的性能。

Web Server启动时载入FastCGI进程管理器(Apache Module或IIS ISAPI等)

  1.  

FastCGI进程管理器自身初始化,启动多个CGI解释器进程(可建多个php-cgi),并等待来自Web Server的连接。

  1.  

当客户端请求到达Web Server时,FastCGI进程管理器选择并连接到一个CGI解释器。Web server将CGI环境变量和标准输入发送到FastCGI子进程php-cgi。

  1.  

FastCGI子进程完成处理后,将标准输出和错误信息从同一连接返回Web Server。当FastCGI子进程关闭连接时,请求便告处理完成。FastCGI子进程接着等待,并处理来自FastCGI进程管理器(运行在Web Server中)的下一个连接。在CGI模式中,php-cgi在此便退出了。


FastCGI与CGI特点:

对于CGI来说,每一个Web请求PHP都必须重新解析php.ini、重新载入全部扩展,并重新初始化全部数据结构。而使用FastCGI,所有这些都只在进程启动时发生一次。一个额外的好处是,持续数据库连接(Persistent database connection)可以工作。

  1.  

由于FastCGI是多进程,所以比CGI多线程消耗更多的服务器内存,php-cgi解释器每进程消耗7至25兆内存,将这个数字乘以50或100就是很大的内存数。


PHP-FPM介绍
要了解PHP-FPM,就得先说说PHP-CGI。
PHP-CGI就是PHP实现的自带的FastCGI管理器。虽然是php官方出品,但是这丫的却一点也不给力,性能太差,而且也很麻烦不人性化,主要体现在:

php-cgi变更php.ini配置后,需重启php-cgi才能让新的php-ini生效,不可以平滑重启。

  1.  

直接杀死php-cgi进程,php就不能运行了。

The above two problems have caused many people to become sick for a long time, so many people have been using the Module method. Until 2004, a diaosi named Andrei Nigmatulin invented PHP-FPM. The emergence of this artifact completely broke this situation. This is a PHP-specific fastcgi manager, which overcomes the above two problems very well, and, It also showed stronger performance in other areas.

In other words, PHP-FPM is a specific implementation of the FastCGI protocol. It is responsible for managing a process pool to process requests from the Web server. Currently, after PHP5.3, PHP-FPM is built into PHP .

Because PHP-CGI is just a CGI program, it can only parse the request itself and return the result without process management. So there are some programs that can schedule php-cgi processes, such as spawn-fcgi separated by lighthttpd. Similarly, PHP-FPM is also a management program for scheduling and managing the PHP parser php-cgi.

PHP-FPM can realize a smooth restart after php.ini modification by generating a new child process.


Summary
Finally, let's summarize what problems these technologies can solve after continuous upgrades (otherwise they won't be upgraded).
image
Therefore, if you want to build a high-performance PHP WEB server, the best way at present is Apache/Nginx  +  FastCGI  +  PHP-FPM (+PHP-CGI) mode, don't use Module loading or CGI mode anymore:)


Guess you like

Origin blog.51cto.com/15127568/2667052