其实理解了以下几个概念,就会明白本文要讲解的问题。CGICGI的全称是“CommonGatewayInterface”,是HTTP服务器与你或其他机器上的程序“对话”的工具,它的程序必须运行在网络服务器上。CGI本身可以看作是一种协议标准,它可以用任何语言编写出符合接口标准的特定协议,只要该语言有标准的输入、输出和环境变量即可。如php,perl,tcl等。FastCGIFastCGI就像一个常驻(long-live)的CGI,可以一直执行,只要激活,不会每次都fork耗时(这是最受批评的CGI的fork-and-execute模式)。它还支持分布式计算,即FastCGI程序可以在Web服务器以外的主机上执行,并接受来自其他Web服务器的请求。FastCGI是一个开放的CGI扩展,具有独立于语言、可扩展的体系结构。它的主要行为是将CGI解释器进程保存在内存中,从而获得更高的性能。众所周知,CGI解释器的重复加载是导致CGI性能低下的主要原因。如果CGI解释器保存在内存中并接受FastCGI进程管理器调度,它可以提供良好的性能、可扩展性、故障转移特性等。FastCGI也可以称为协议标准。比如下面提到的php-fpm就是一个支持解析php的fastCGI进程管理器/引擎。FastCGI特性FastCGI是独立于语言的。FastCGI进程内应用程序独立于核心Web服务器运行,提供比API更安全的环境。API将应用程序代码与核心Web服务器链接起来,这意味着应用程序在一个错误的API上可能会损坏其他应用程序或核心服务器。恶意API应用程序代码甚至可以从另一个应用程序或核心服务器窃取密钥。FastCGI技术目前支持的语言有:C/C++、Java、Perl、Tcl、Python、SmallTalk、Ruby等,相关模块也可在Apache、ISS、Lighttpd等流行的服务器上使用。FastCGI不依赖于内部架构任何Web服务器,因此即使服务器技术发生变化,FastCGI仍保持稳定。FastCGIWebServer工作原理WebServer启动时加载FastCGI进程管理器(IISISAPI或ApacheModule),FastCGI进程管理器初始化自身,启动多个CGI解释器进程(可见多个php-cgi)并等待连接从网络服务器。当客户端请求到达Web服务器时,FastCGI进程管理器选择并连接到CGI解释器。Web服务器将CGI环境变量和标准输入发送到FastCGI子进程php-cgi。FastCGI子进程完成处理后,它会从同一连接向Web服务器返回标准输出和错误消息。当FastCGI子进程关闭连接时,请求被处理。FastCGI子进程然后等待并处理来自FastCGI进程管理器(在Web服务器中运行)的下一个连接。在CGI模式下,php-cgi在这里退出。在上面的例子中,你可以想象CGI通常有多慢。每次web请求PHP都必须重新解析php.ini,重新加载所有扩展并重新初始化所有数据结构。使用FastCGI,所有这些只发生一次,即在进程启动时。一个额外的好处是持久数据库连接(Persistentdatabaseconnection)可以工作。FastCGI的缺点是因为是多进程,所以比CGI多线程消耗更多的服务器内存。PHP-CGI解释器每个进程消耗7到25兆字节的内存。将此数字乘以50或100就是大量内存。Nginx0.8.46+PHP5.2.14(FastCGI)服务器3万并发下,10个Nginx进程启动消耗150M内存(15M*10=150M),64个php-cgi进程启动消耗1280M内存(20M*64=1280M),加上系统本身消耗的内存,总内存消耗不到2GB。如果服务器内存小,只能开启25个php-cgi进程,这样php-cgi消耗的总内存只有500M。以上数据摘自Nginx0.8.x+PHP5.2.13(FastCGI)搭建比Apache好十倍的web服务器(版本6)PHP-CGIPPHP-CGI是PHP自带的FastCGI管理器。PHP-CGI的不足:php-cgi更改php.ini配置后,需要重启php-cgi才能使新的php-ini生效,无法平滑重启。直接killphp-cgi进程,php无法运行。(PHP-FPM和Spawn-FCGI没有这个问题,daemon进程会顺利的重新生成新的子进程。)PHP-FPPMHP-FPM是一个PHPFastCGI管理器,只用于PHP,可以在http://从php-fpm.org/download下载。PHP-FPM其实是PHP源码的一个补丁,旨在将FastCGI进程管理集成到PHP包中。必须打补丁到你的PHP源码中,编译安装PHP后才能使用。现在我们可以下载最新的PHP5.3.2源码树中直接集成PHP-FPM的分支。据说下个版本会集成到PHP的主分支中。与Spawn-FCGI相比,PHP-FPM对CPU和内存的控制更好,前者容易崩溃,必须用crontab监控,而PHP-FPM则没有这些烦恼。PHP5.3.3已经集成了php-fpm,不再是第三方包。PHP-FPM提供了更好的PHP进程管理方式,可以有效控制内存和进程,可以平滑的重新加载PHP配置。它比spawn-fcgi有更多优点,所以被PHP官方收录。可以使用./configure中的–enable-fpm参数启用PHP-FPM。Spawn-FCGISpawn-FCGI是一个通用的FastCGI管理服务器,它是lighttpd的一部分。很多人使用Lighttpd的Spawn-FCGI以FastCGI方式进行管理,但是也有很多不足之处。PHP-FPM的出现在一定程度上缓解了一些问题,但是PHP-FPM的一个缺点是需要重新编译,对于一些已经运行的环境可能会有很大的风险(参考),直接在php中使用5.3.3PHP-FPM启动。Spawn-FCGI现在已经成为一个独立的项目,更加稳定,也为很多网站的配置带来了方便。很多网站都用它搭配nginx来解决动态网页。最新的lighttpd不包括这块(http://www.lighttpd.net/search?q=Spawn-FCGI),但在以前的版本中可以找到。包含在lighttpd-1.4.15版本(http://www.lighttpd.net/download/lighttpd-1.4.15.tar.gz),目前Spawn-FCGI下载地址为http://redmine.lighttpd.net/projects/spawn-fcgi,最新版本为http://www.lighttpd.net/download/spawn-fcgi-1.6.3.tar.gz。注:最新的Spawn-FCGI可以到lighttpd.net网站搜索“Spawn-FCGI”找到其最新版本发布地址。PHP-FPM与spawn-CGI对比,PHP-FPM的使用非常方便。配置都在PHP-FPM.ini文件中,启动和重启可以从php/sbin/PHP-FPM进行。更方便的是,修改php.ini后,直接使用PHP-FPMreload加载即可,无需杀进程即可完成php.ini的修改。加载结果表明,使用PHP-FPM可以大大提高PHP的性能。PHP-FPM控制的进程CPU回收速度比较慢,内存分配很均匀。Spawn-FCGI控制的进程CPU下降很快,内存分配比较不均匀。有很多进程好像是未分配的,而有的进程是高的。可能是流程任务分配不均造成的。而这也会导致整体响应能力的下降。而PHP-FPM的合理分配导致提到了整体响应和任务的平均值。总结: fastCGI是nginx和php的通信接口。这个接口的实际过程是通过启动php-fpm进程来解析php脚本的,也就是说php-fpm相当于一个动态的应用服务器,让nginx动态解析php。因此,如果nginx服务器需要支持php解析,需要在nginx.conf中添加php配置:将php脚本转发到fastCGI进程监听的IP地址和端口(在php-fpm.conf中指定)。同时,安装php时需要开启fastCGI选项,并编译安装php-fpm补丁/扩展。同时需要启动php-fpm进程来解析nginx通过fastCGI转发过来的php脚本。
