CGI, FastCGI, PHP-FPM, SPAWN-FCGI, Nginx 它们之间的关系

说明:在好长一段时间里,我都不知道 CGI, FastCGI, PHP-FPM, SPAWN-FCIG, Nginx这些协议和软件他们之间到底是一种什么关系? 为什么会有这么多的软件,协议呢?他们之间是怎么协同工作的?为了弄懂他们之间的关系,我看了一些文章,在此做个笔记。

一:sapi和cgi, fastcig, cli的关系?

在php中, sapi是cgi, fastcgi,cli实现的统称。
SAPI: Server Application Programming Interface-服务器公共网关接口. (php里面封装了很多SAPI, 它的作用是和其他的http服务器交互)。
有了这个公共接口,那么PHP解析器http服务器 就可以解耦, php解析器(进程来看表现就是php-cgi这个进程)和 http服务器可以独自运行, 通过sapi彼此之间进行通信, 而2者之间进行通信的格式标准是什么呢? 就是CGI,

sapi实现了cgi这个协议.

二:什么是CLI, CGI, FastCGI

2.1 CLI: 名称是 command line interface - 命令行公共接口
比如你在shell在运行php的时候,就是通过这个接口和php解析器交互的.

2.2 CGI: Common Gateway Interface - 公共网关接口
它是一个协议. 假如apache得到一个request信息, 那么它就 fork一个进程出来, 接管这个request请求, 这样的弊端是,每次请求都要fork一个进程出来, 性能不行

2.3 FastCGI - CGI 的改进版本
它是cgi的一个改进版本,为什么要这个改进版本呢?因为cgi的性能比较差。 如果动态请求进来的时候,服务器都得fork出一个进程出来,而fork出进程过程中,它还要执行很多初始化的操作,
php环境初始化,变量初始化, Module 的初始化,还有 request 的初始化,php解析器执行玩这个请求后,module的关闭操作, request的关闭操作.

而fastcgi就简略了其中的几个环节。它会根据配置文件先fork出几个php-cgi的常驻进程,请求来了,其中的一个php-cgi就会接管这个进程,处理完后,就会关闭这个request.
它少了php环境初始化,Module初始化,Module关闭。 它只执行 request初始化和 request关闭。因为前面几个步骤是随着http服务器就已经初始化好了.

三: http服务器, cgi/FastCGI 和 php解析器 之间的关系?

客户端通过http协议过来的请求,如果是静态文件(html,jpg), 那么http服务器,比如nginx服务器,就会直接返回静态文件给客户端用户, 而不需要和cgi/FastCGI通信。这也可以说明为什么访问静态文件效率高,执行会很快,因为少了后面的执行流程。跑题了,- -!

如果是动态文件,比如以 .php 结尾的文件,那么nginx就会转发这个请求给后端的php解析器,让它来处理这个请求。 nginx是通过什么来和php解析器通信的呢? 就是cgi/FastCGI 这个标准协议来传递数据的。

http服务器又是通过什么和cgi/FastCGI通信的呢?
通过unix socket, socket, ip方式来进行通信.

四: php-fpm 和 spawn-fcgi是什么?

FastCGI以接口的方式在脚本解析器上启动一个或多个守护进程,也就是php-cgi,这些进程就是FastCGI管理器,而这些进程是哪个来管理的呢?就是php-fpmspawn-fcgi,他们就是支持php的2个FastCGI进程管理器。
spawn-fcgi 原先是 lighttpd 里面的, 目前已经独立成一个项目。 所以他现在也可以支持 Nginx.
php-fpmspawn-fcgi提供了更好的php进程管理方式, 可以有效的控制内存和进程,可以平滑重载php配置.
在php5.3.3 已经集成了php-fpm,用编译方式安装PHP,在./configure的时候带—enable-fpm参数即可开启php-fpm。

php-cgi 是运行php
php-fpm, spawn-fcgi是守护php-cgi进程

五:FastCGI的工作原理

一般情况下,FastCGI的整个工作流程是这样的:

  1. Web Server启动时载入FastCGI进程管理器(IIS ISAPI或Apache Module)
  2. FastCGI进程管理器自身初始化,启动多个CGI解释器进程(可见多个php-cgi)并等待来自Web Server的连接。
  3. 当客户端请求到达Web Server时,FastCGI进程管理器选择并连接到一个CGI解释器。 Web server将CGI环境变量和标准输入发送到FastCGI子进程php-cgi。
  4. FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回Web Server。当FastCGI子进程关闭连接时, 请求便告处理完成。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在Web Server中)的下一个连接。 在CGI模式中,php-cgi在此便退出了。

六:参考链接

http://ixdba.blog.51cto.com/2895551/806622/
http://segmentfault.com/q/1010000000256516
http://bbs.csdn.net/topics/350103512
http://www.php-internals.com/book/?p=chapt02/02-02-03-fastcgi

如果有什么错误的地方,还请大家指出来, 我一定改正,向大家好好学习.