CGI 全称是 “公共网关接口”(Common Gateway Interface),HTTP 服务器与你的或其它机 器上的程序进行 “交谈” 的一种工具,其程序须运行在网络服务器上。CGI 本身可以看成是一种协议标准,它可以用任何一种语言编写具体的符合该接口标准的 协议存在,只要这种语言具有标准输入、输出和环境变量。如 php,perl,tcl 等。
方法 / 步骤
FastCGIFastCGI 像是一个常驻 (long-live) 型的 CGI,它可以一直执行着,只要激活后,不会每次 都要花费时间去 fork 一次(这是 CGI 最为人诟病的 fork-and-execute 模式)。它还支持分布式的运算,即 FastCGI 程序可以在网站服务器以外的主机上执行并且接受来自其它网站服务器来的请求。FastCGI 是语言无关的、可伸缩架构的 CGI 开放扩展,其主要行为是将 CGI 解释器进程保持 在内存中并因此获得较高的性能。众所周知,CGI 解释器的反复加载是 CGI 性能低下的主要原因,如果 CGI 解 释器保持在内存中并接受 FastCGI 进程管理器调度,则可以提供良好的性能、伸缩性、Fail- Over 特性等等 。FastCGI 也可以称为是一种协议标准,比如下面要说的 php-fpm 就是支持解析 php 的 一个 fastCGI 进程管理器 / 引擎。
FastCGI 特点 FastCGI 具有语言无关性.FastCGI 在进程中的应用程序,独立于核心 web 服务器运行,提供了一 个比 API 更安全的环境。APIs 把应用程序的代码与核心的 web 服务器链接在一起,这意味着在一个错误的 API 的应用程序可能会损坏其他应用程序或核心服务器。 恶意的 API 的应用程序代码甚至可以窃取另一个应用 程序或核心服务器的密钥。FastCGI 技术目前支持语言有:C/C++、Java、Perl、Tcl、Python、 SmallTalk、Ruby 等。相关模块在 Apache, ISS, Lighttpd 等流行的服务器上也是可用的。FastCGI 的不依赖于任何 Web 服务器的内部架构,因此即使服务器技术 的变化,FastCGI 依然稳定不变。
FastCGI 的工作原理 Web Server 启动时载入 FastCGI 进程管理器(IIS ISAPI 或 Apache Module) FastCGI 进程管理器自身初始化,启动多个 CGI 解释器进程 (可见多个 php-cgi) 并等待来自 Web Server 的连接。当客户端请求到达 Web Server 时,FastCGI 进程管理器选择并连接到一 个 CGI 解释器。Web server 将 CGI 环境变量和标准输入发送到 FastCGI 子进程 php-cgi。FastCGI 子进程完成处理后将标准输出和错误信息从同一连接返回 Web Server。当 FastCGI 子进程关闭连接时,请求便告处理完成。FastCGI 子进程接着等待并处理来自 FastCGI 进 程管理器 (运行在 Web Server 中) 的下一个连接。 在 CGI 模式中,php-cgi 在此便退出了。在上述情况中,你可以想象 CGI 通常有多慢。每一个 Web 请求 PHP 都必须重新解析 php.ini 、重新载入全部扩展并重初始化全部数据结构。使用 FastCGI,所有这些都只在进程启动时发生一次。一个 额外的好处是,持续数据库连接 (Persistent database connection) 可以工作。
FastCGI 的不足因为是多进程,所以比 CGI 多线程消耗更多的服务器内存,PHP-CGI 解释器每进程消耗 7 至 25 兆内存,将这个数字乘以 50 或 100 就是很大的内存数。Nginx 0.8.46+PHP 5.2.14 (FastCGI) 服务器在 3 万并发连接下,开启的 10 个 Nginx 进程消 耗 150M 内存(15M*10=150M),开启的 64 个 php-cgi 进程消耗 1280M 内存(20M*64=1280M),加上系统自身消 耗的内存,总共消耗不到 2GB 内存。如果服务器内存较小,完全可以只开启 25 个 php-cgi 进程,这样 php-cgi 消耗的总内存数才 500M。上面的数据摘自 Nginx 0.8.x + PHP 5.2.13 (FastCGI) 搭建胜过 Apache 十倍的 Web 服务器 (第 6 版)
PHP-CGIPHP-CGI 是 PHP 自带的 FastCGI 管理器。PHP-CGI 的不足:php-cgi 变更 php.ini 配置后需重启 php-cgi 才能让新的 php-ini 生效, 不可以平滑重启。直接杀死 php-cgi 进程,php 就不能运行了。(PHP-FPM 和 Spawn-FCGI 就 没有这个问题,守护进程会平滑从新生成新的子进程。)
PHP-FPMPHP-FPM 是一个 PHP FastCGI 管理器,是只用于 PHP 的,可以在 http://php- fpm.org/download 下载得到。PHP-FPM 其实是 PHP 源代码的一个补丁,旨在将 FastCGI 进程管理整合进 PHP 包中。必须将 它 patch 到你的 PHP 源代码中,在编译安装 PHP 后才可以使用。现在我们可以在最新的 PHP 5.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 有个缺点就是要重新编译,这对于一些已经运行的环境可能有不小的风险 (refer),在 php 5.3.3 中可以直接使用 PHP-FPM 了。
Spawn-FCGI 目前已经独成为一个项目,更加稳定一些,也给很多 Web 站点的配置带来便利。已经有不少站点将它与 nginx 搭配来解决动态网页。
PHP-FPM 与 spawn-CGI 对比 PHP-FPM 的使用非常方便,配置都是在 PHP-FPM.ini 的文件内,而启动、重启都可以从 php/sbin/PHP-FPM 中进行。更方便的是修改 php.ini 后可以直接使用 PHP-FPM reload 进行加载,无需杀掉进 程就可以完成 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 脚本。