CGI、FastCGI和php-fpm的概念和区别

时间:2022-10-26 16:28:06

在2000年或更早的时候,CGI比较盛行。那时,Perl是编写CGI的主流语言,以至于一般的CGI程序就是Perl程序。

由于CGI程序的性能极其低下且安全性较差,现在基本没人使用。越来越多的人开始使用Web服务器内置模块和FastCGI程序。例如,apache服务器的mod_php,nginx服务器对FastCGI的支持。

1. CGI

CGI(Common Gateway Interface),公共网关接口,它是Web服务器与外部应用程序(CGI程序)之间传递信息的接口标准。通过CGI接口,Web服务器就能够获取客户端提交的信息,并转交给服务器端的CGI程序处理,最后返回结果给客户端。

也就是说,CGI实际上是一个接口标准。我们通常所说的CGI是指CGI程序,即实现了CGI接口标准的程序。

只要某种语言具有标准输入、输出和环境变量,如perl、php、C等,就可以用来编写CGI程序。

CGI程序的工作方式:

Web服务器一般只处理静态文件请求(如 jpg、htm、html),如果碰到一个动态脚本请求(如php),web服务器主进程,就fork出一个新的进程来启动CGI程序,也就是说将动态脚本请求交给CGI程序来处理。启动CGI程序需要一个过程,比如,读取配置文件,加载扩展等。CGI程序启动后,就会解析动态脚本,然后将结果返回给Web服务器,最后Web服务器再将结果返回给客户端,刚才fork的进程也会随之关闭。

这样,每次用户请求动态脚本,Web服务器都要重新fork一个新进程,去启动CGI程序,由CGI程序来处理动态脚本,处理完后进程随之关闭。

这种工作方式的效率是非常低下的。

2. Web服务器内置模块

后来,出现了一种比较高效的方式:Web服务器内置模块。例如,apache的mod_php模块。将php解释器做成模块,然后加载到apache服务器中。

这样,apache服务器在启动的时候,就会同时启动php模块。当客户端请求php文件时,apache服务器就不用再fork出一个新进程来启动php解释器,而是直接将php文件交给运行中的php模块处理。显然,这种方式下,效率会比较高。

由于在apache服务器启动时,才会读取php的配置文件,加载php模块,在apache的运行过程中 ,不会再重新读取php的配置文件。所以,每次我们修改了php的配置文件后,必须重启apache,新的php配置文件才会生效。

3. FastCGI

FastCGI就像是一个常驻(long-live)型的CGI程序,它可以一直运行着。FastCGI程序也可以和Web服务器分别部署在不同的主机上,它还可以接受来自其他Web服务器的请求。

FastCGI也是语言无关的。其主要行为是将CGI解释器进程保持在内存中并因此获得高效的性能。众所周知,CGI解释器的反复加载是CGI性能低下的主要原因。

FastCGI是一种进程管理工具,它可以在内存中管理CGI进程。

FastCGI进程管理器需要单独启动。启动FastCGI后,会生成一个FastCGI主进程和多个子进程(子进程其实就是CGI解释器进程)。

当客户端请求Web服务器上的动态脚本时,Web服务器会将动态脚本通过TCP协议交给FastCGI主进程,FastCGI主进程根据情况,安排一个空闲的子进程来解析动态脚本,处理完成后将结果返回给Web服务器,Web服务器再将结果返回给客户端。该客户端请求处理完毕后,FastCGI子进程并不会随之关闭,而是继续等待主进程安排工作任务。

由此可知,FastCGI的工作效率是非常高的。

4. php-fpm

fpm是FastCGI Process Manager的缩写,那么,fpm就是FastCGI进程管理器的简称。

php-fpm就是php中的FastCGI进程管理器。

对于php5.3之前的版本来说,php-fpm是一个第三方的补丁包,旨在将FastCGI进程管理整合进PHP包中。

在php5.3之后的版本中,php-fpm不再是第三方的包,它已经被集成到php的源码中了。php-fpm提供了更好的PHP进程管理方式,可以有效控制内存和进程、可以平滑重载PHP配置,比spawn-fcgi具有更多优点,所以php-fpm被PHP官方收购了。