CGI/FastCGI/PHPCGI/PHPFPM

编程

1,CGI  (Common Gateway Interface 公共网关接口)

先来了解一下网关是什么含义,从宏观定义上来说,只要连接两个不同的网络的设备都可以叫网关。CGI 就是 Web Server(如Nginx) 与 PHP应用 进行沟通 的一种工具及其所规定的一整套协议。CGI可以用任何一种语言编写,只要这种语言具有标准输入、输出和环境变量。如php、perl、tcl等。

例如,当HTTP请求到达Nginx时,这个请求如何到达后方的PHP应用呢?同时,这个携带了很多数据,比如,请求URL,method,参数,HTTP header等等,这些数据怎么传递给后方的PHP应用呢?当PHP应用处理了请求后,怎么把处理结果反馈给Nginx呢?如此种种的工作,就由CGI来协调和完成。

1.1 优点

CGI完全独立于任何服务器,仅仅是做为中间分子,提供接口给Web Server 和 PHP,两者通过 CGI 来进行沟通,尽量减少两者的关联。

1.2 缺点

fork-and-execute模式:CGI处理每一次Web请求时,PHP都会去解析php.ini,加载入全部扩展并初始化全部数据结构,性能低下,特别是在并发量大的情况下。

 

2,FastCGI

如上面所说,CGI解释器会反复加载,性能低下。如果CGI解释器保持在内存中,并接受FastCGI进程管理器调度,则可以提供良好的性能、伸缩性、Fail-Over特性等等。

FastCGI是一个内存常驻型(Long-Live)的CGI,它只要激活后,就可以一直在内存中常驻执行,不会每次都要花费时间去fork一次。另一个额外的好处是,持续数据库连接(Persistent database connection)可以工作。

FastCGI是语言无关的,可伸缩架构的CGI开放扩展,其主要行为是将CGI解释器进程保持在内存中并因此获得较高的性能。

2.1 FastCGI特点

2.1.1 FastCGI具有语言无关性,目前支持语言有C/C++、Java、Perl、Tcl、Python、SmallTalk、Ruby等。

2.1.2 FastCGI不依赖于任何Web服务器的内部架构,提供了一个比API更安全的环境。

2.2 FastCGI的工作原理

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

过程如下:

2.2.1 Web Server启动时载入FastCGI进程管理器;
2.2.2 FastCGI进程管理器自身初始化,启动多个CGI解释器进程(可见多个php-cgi)并等待来自Web Server的连接;
2.2.3 当HTTP请求到达Web Server时,FastCGI进程管理器选择并连接到一个CGI解释器。Web Server将CGI环境变量和标准输入发送到FastCGI子进程php-cgi;
2.2.4 FastCGI子进程php-cgi完成处理后,将标准输出和错误信息从同一连接返回Web Server。
2.2.5 当FastCGI子进程关闭连接时,请求便告处理完成。FastCGI子进程接着等待着处理来自FastCGI进程管理器的下一个连接。 在CGI模式中,php-cgi在此便退出了。

2.3 FastCGI优点

FastCGI随着Web Server启动,并常驻在内存中,事先启动多个CGI解释器进程(PHP-CGI)去处理Web请求,相对于CGI而言,节省了每次PHP启动,解析,加载和关闭的时间,提高了性能。

2.4 FastCGI的缺点

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

 

3,PHP-CGI

PHP-CGI是PHP官方自带的FastCGI管理器。虽然是php官方出品,但是性能太差,而且也很麻烦,主要体现在:

3.1 PHP-CGI的缺点

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

3.1.2 PHP-CGI自己本身只能解析请求,返回结果,不会进程管理。直接杀死php-cgi进程后,php就不能运行了。(PHP-FPM和Spawn-FCGI就没有这个问题,守护进程会平滑地生成新的子进程。)

上面2个问题,一直让很多人病垢了很久,所以很多人一直还是在用 Module 方式。 直到 2004年Andrei Nigmatulin发明了PHP-FPM,这神器的出现就彻底打破了这种局面,这是一个PHP专用的 fastcgi 管理器,它克服了上面两个问题,而且,还在其他方面还有更表现强劲。

 

4,PHP-FPM

PHP-FPM是对于 FastCGI 协议的一种具体实现,因此它也是用于调度管理PHP解析器php-cgi的管理程序。
它提供了更好的PHP进程管理方式,可以有效控制内存和进程。在修改php.ini文件后,通过master生成新的worker子进程,就实现了平滑重启。

 

5,总结

由上可知,这些进程管理工具,总是为了解决现有工具存在的不足而产生的。FastCGI通过常驻内存,解决了CGI的Fork-and-Execute模式问题,提升了性能。PHP-CGI虽然是官方的FastCGI管理器,但是修改配置后不能平滑重启,而PHP-FPM解决了这个问题。

6,Nginx+FastCGI / PHP-FPM运行原理

Nginx不支持对外部程序的直接调用或者解析,所有的外部程序(包括PHP)必须通过FastCGI接口来调用。
FastCGI接口在Linux下是socket,(这个socket可以是文件socket,也可以是ip socket,例如 127.0.0.1:9000)。为了调用CGI程序,还需要一个FastCGI的wrapper(wrapper可以理解为用于启动另一个程序的程序),这个wrapper绑定在某个固定socket上,如端口或者文件socket。

6.1 当Nginx将CGI请求发送给这个socket的时候,
6.1.1 如果是FastCGI,通过FastCGI(PHP-FPM)接口,wrapper接纳到请求,
然后派生出一个新的线程。
6.1.2 如果是PHP-FPM,则它的master进程监听到nginx请求后,会将请求分配给其中一个闲置的worker进程;
6.2 这个线程 / PHP-FPM worker,调用解释器,执行请求;
6.3, wrapper / worker将返回的数据通过FastCGI接口,沿着固定的socket传递给Nginx;
6.4 Nginx将返回的数据发送给客户端。

以上是 CGI/FastCGI/PHPCGI/PHPFPM 的全部内容, 来源链接: utcz.com/z/516263.html

回到顶部