FastCGI 是语言无关的、可伸缩架构的 CGI 开放扩展,其主要行为是将 CGI 解释器进程保持在内存中并因此获得较高的性能。众所周知,CGI 解释器的反复加载是 CGI 性能低下的主要原因,如果 CGI 解释器保持在内存中并接受 FastCGI 进程管理器调度,则可以提供良好的性能、伸缩性、Fail-Over特性等等。
CGI 全称 “通用网关接口”(Common Gateway Interface),用于 HTTP 服务器与其它机器上的程序服务通信交流的一种工具,CGI 程序须运行在网络服务器上。
传统 CGI 接口方式的主要缺点是性能较差,因为每次 HTTP 服务器遇到动态程序时都需要重启解析器来执行解析,然后结果被返回给 HTTP 服务器。这在处理高并发访问几乎是不可用的,因此就诞生了 FastCGI。另外传统的 CGI 接口方式安全性也很差。
FastCGI 是一个可伸缩地、高速地在 HTTP 服务器和动态脚本语言间通信的接口(FastCGI 接口在 Linux 下是 socket(可以是文件 socket,也可以是 ip socket)),主要优点是把动态语言和 HTTP 服务器分离开来。多数流行的 HTTP 服务器都支持 FastCGI,包括 Apache、 Nginx 和 lightpd。
同时,FastCGI 也被许多脚本语言所支持,比较流行的脚本语言之一为 PHP。FastCGI 接口方式采用 C/S 架构,可以将 HTTP 服务器和脚本解析服务器分开,同时在脚本解析服务器上启动一个或多个脚本解析守护进程。当 HTTP 服务器每次遇到动态程序时,可以将其直接交付给 FastCGI 进程执行,然后将得到的结构返回给浏览器。这种方式可以让 HTTP 服务器专一地处理静态请求或者将动态脚本服务器的结果返回给客户端,这在很大程度上提高了整个应用系统的性能。
首先 Fastcgi 会先启动一个 master,解析配置文件,初始化执行环境,然后再启动多个 worker。当请求过来时,master 会传递给一个 worker,然后立即可以接受下一个请求。这样就避免了重复的劳动,效率自然是高。
而且当 worker 不够用时,master 可以根据配置预先启动几个 worker 等着;当然空闲 worker 太多时,也会停掉一些,这样就提高了性能,也节约了资源。这就是 fastcgi 对进程的管理。
php 的解析器是 php-cgi。php-cgi 只是个 CGI 程序,他自己本身只能解析请求,返回结果,不会进程管理,所以就出现里一些能够调度 php-cgi 进程的程序,而 PHP-FPM 就是能够调度 php-cgi 进程的程序中的一种。PHP-FPM 在长时间的发展后,逐渐得到了大家的认可。
PHP-FPM 其实是 PHP 源代码的一个补丁,旨在将 FastCGI 进程管理整合进 PHP 包中。必须将它 patch 你的 PHP 源代码中,在编译安装 PHP 后才可以使用。PHP5.3.3 已经继承 php-fpm 了,不再是第三方的包了。PHP-FPM 提供了更好的 PHP 进程管理方式,可以有效控制内存和进程,可以平滑重载 PHP 配置。
Nginx 不支持对外部动态程序的直接调用或者解析,所有的外部程序(包括 PHP)必须通过 FastCGI 接口来调用。FastCGI 接口在 Linux 下是 socket(可以是文件 socket,也可以是 ip socket)。
为了调用 CGI 程序,还需要一个 FastCGI 的 wrapper,这个 wrapper 绑定在某个固定 socket 上,如端口或者文件 socket。当 Nginx 将 CGI 请求发送给这个 socket 的时候,通过 FastCGI 接口,wrapper 接收到请求,然后派生出一个新的线程,这个线程调用解释器或者外部程序处理脚本并读取返回数据;接着,wrapper 再将返回的数据通过 FastCGI 接口,沿着固定的 socket 传递给 Nginx;最后,Nginx 将返回的数据发送给客户端,这就是 Nginx+FastCGI 的整个运作过程。
FastCGI 的主要优点是把动态语言和 HTTP 服务器分离开来,是 Nginx 专一处理静态请求和向后转发动态请求,而 PHP/PHP-FPM 服务器专一解析 PHP 动态请求。具体配置如下:
我们也可以将 FastCGI 的工作过程总结为如下:
FastCGI 是语言无关的、可伸缩架构的 CGI 开放扩展,其主要行为是将 CGI 解释器进程保持在内存中并因此获得较高的性能。