关于CGI、FASTCGI、PHP-CGI、PHP-FPM

因为想了解PHP的运行原理,所以了解到需要知道这几个比较陌生的东西,在网上搜到很多,总说纷纭,大致做了一些总结,方便理解。

说明:以下web server以nginx为例,语言以php为例

1,CGI

CGI(Common Gateway Interface)公共网关接口。首先要说明的是,CGI是一个协议,与语言无关。因为nginx和php的语言不通,因此需要一个沟通转换的过程,而CGI就是这个沟通的协议,为了保证web service传递过来的数据是标准格式的,方便CGI程序的编写者。Web Service只是内容的分发者,他们通过这个协议来进行沟通。

比如,如果请求/index.html,那么Web Server会去文件系统中找到这个文件,发送给浏览器,这里分发的是静态数据。好了,如果现在请求的是/index.php,根据配置文件,Nginx知道这个不是静态文件,需要去找PHP解析器来处理,那么他会把这个请求简单处理后交给PHP解析器。Nginx会传哪些数据给PHP解析器呢?url要有吧,查询字符串也得有吧,POST数据也要有,HTTP header不能少吧,好的,CGI就是规定要传哪些数据、以什么样的格式传递给后方处理这个请求的协议。仔细想想,你在PHP代码中使用的用户从哪里来的。

当Web Server收到/index.php这个请求后,会启动对应的CGI程序,这里就是PHP的解析器。接下来PHP解析器会解析php.ini文件,初始化执行环境,然后处理请求,再以规定CGI规定的格式返回处理后的结果,退出进程。web server再把结果返回给浏览器。

2,CGI的缺点

CGI协议每次在请求后端服务时都要启动实现CGI协议的程序,这里就是PHP解析器。PHP解析器会解析PHP.ini文件,进行初始化工作,处理请求、返回结果。每个请求都要重新初始化,工作太冗余。所以,FCGI应运而生。 因为PHP是解释型语言,因此需要解释器去解释PHP代码。

3,FASTCGI

首先,Fastcgi是CGI的升级版,一种语言无关的协议,FastCGI是用来提高CGI程序性能的。

4,FASTCGI的运行原理

首先,FastCGI会先启一个master,解析配置文件,初始化执行环境,然后再启动多个worker。当请求过来时,master会传递给一个worker,然后立即可以接受下一个请求。这样就避免了重复的劳动,效率自然是高。而且当worker不够用时,master可以根据配置预先启动几个worker等着;当然空闲worker太多时,也会停掉一些,这样就提高了性能,也节约了资源。

详细过程:

(1),Web Server启动时载入FastCGI进程管理器

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

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

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

5,FASTCGI的不足之处

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

6,PHP-CGI

php-cgi是CGI协议的一个实现,它是php的解释器,php-cgi只是个CGI程序,他自己本身只能解析请求,返回结果,不会管理进程,所以就出现了一些能够调度php-cgi进程的程序,比如说由lighthttpd分离出来的spawn-fcgi。它的不足之处就是:php-cgi变更php.ini配置后需重启php-cgi才能让新的php-ini生效,不可以平滑重启。

7,PHP-FPM

php-fpm是php提供给web serve也就是http前端服务器的fastcgi协议接口程序,它不会像php-cgi一样每次连接都会重新开启一个进程,处理完请求又关闭这个进程,而是允许一个进程对多个连接进行处理,而不会立即关闭这个进程,而是会接着处理下一个连接。它可以说是php-cgi的一个管理程序,是对php-cgi的改进。

php-fpm会开启多个php-cgi程序,并且php-fpm常驻内存,每次web serve服务器发送连接过来的时候,php-fpm将连接信息分配给下面其中的一个子程序php-cgi进行处理,处理完毕这个php-cgi并不会关闭,而是继续等待下一个连接,这也是fast-cgi加速的原理,但是由于php-fpm是多进程的,而一个php-cgi基本消耗7-25M内存,因此如果连接过多就会导致内存消耗过大,引发一些问题,例如nginx里的502错误。

8,PHP-FPM的其它功能

平滑过渡配置更改,普通的php-cgi在每次更改配置后,需要重新启动才能初始化新的配置,而php-fpm是不需要,php-fpm分将新的连接发送给新的子程序php-cgi,这个时候加载的是新的配置,而原先正在运行的php-cgi还是使用的原先的配置,等到这个连接后下一次连接的时候会使用新的配置初始化,这就是平滑过渡。

参考:
https://blog.csdn.net/belen_xue/article/details/65950658
https://blog.csdn.net/jinxingfeng_cn/article/details/51894288
http://www.php.cn/php-weizijiaocheng-377248.html

猜你喜欢

转载自blog.csdn.net/self_realian/article/details/82842219