这段时间对Nginx+PHP-FPM的概念和机制一直不太清晰,趁着同事的分享和看过的几篇博文和资料,重新将思路处理一下。

  首先,PHP-FPM(FastCGI Process Manager: FastCGI进程管理器)是一种针对PHP的FastCGI,针对PHP语言的一种进程管理器。FastCGI顾名思义就是一种快速的CGI(Common Gateway Interface)。因此为了能够理解PHP-FPM,我们首先应该了解CGI是怎么样一个机制。

  1   CGI(Common Gateway Interface)

  CGI(通用网关接口)是架起服务器Web Server和处理来自客户端请求的程序之间沟通的桥梁,也就是说是一个第三方的协议规定。当服务器接收到用户端的请求是静态请求时,Web Server会去对应的文件系统中找到这个文件,然后发送给浏览器。但是如果用户的请求是一种动态的请求,Web Server (如Nginx)就不知道如何处理这个请求了,既然自己不知道如何处理,就要求助或者说是承包给第三方。但是交给第三方处理这个请求的时候,总得告诉第三方一些请求的参数吧,这就像软件领域的需求的对接一样,规定我给你什么输入,然后你给我什么输出结果,CGI就是这种约定,规定了输入的参数和输出的结果的一种协议。在处理动态请求的情况下,其流程图如下:

图1 CGI对请求处理流程图

  用文字描述如下:

  1.用户通过Http将动态请求发送到Web Server;

  2.Web Server通过使用unix domain socket,或者ip socket将请求转发给CGI(如果使用ip socket的话,允许将Web Server 和CGI部署在不同的机器上);

  3.CGI fork一个对应的进程处理来自客户端的动态请求,得到执行的结果;

  4.执行的结果经过同一个socket连接通过CGI返回给Web server;

  5.有Web Server将数据发送个客户端;

  也就是说在这个过程中Web Server只是负责执行静态页面的请求以及接受用户的动态请求并转发给相应的处理程序,然后将动态请求处理程序的输出结果返回给客户端。这可以减轻Web Server的工作负担,使得Web Serve能够在更高并发的请求环境中工作。

  2   FastCGI的工作方式

  CGI虽然提供了Web Server和请求处理程序之间的一种接口规范,但是却饱受诟病。如下图所示,其原因在于CGI是以一种按需派生的方式工作的,也就是说在接收到Web Server转发的请求之后,就需要重新fork一个进程处理来自客户端的请求,但是fork一个进程的代价一般比较昂贵。在并发性不是很高的情况下,这种工作方式也许能工作的很好,但是如果并发性很高就会导致频繁的fork进程并处理请求,给运行CGI的机器造成很大的压力。其实仔细分析fork进程(如图3所示)所发生的事情可以清晰地看到有一些步骤是重复进行的,因此这些步骤是可以省略掉的,因此就诞生了FastCGI。FastCGI是在CGI的架构思想的扩展,其核心思想在于在Web Server和CGI之间建立起一个智能的可持续的中间层用于统筹CGI程序的管理,因此FastCGI可以被看做是一个CGI的进程管理器。其工作流程图如下:

图2 FastCGI对请求的处理流程图

  其中的Fastcig-wrapper可以理解为用于启动另一个程序的程序。FastCGI的工作流程如下所述:

  1.FastCGI进程管理器执行自身的初始化,启动多个worker进程并等待来自Web Server的连接,其中启动FastCGI进程的时候可以配置以ip socket和unix domain socket两种方式启动;

  2.当客户端请求到达Web Server的时候,Web Server将请求采用ip socket或者unix domain socket发送到FastCGI的主进程(也叫master进程),master进程选择连接到一个worker进程。Web服务器将CGI的环境变量和标准输入发送到worker进程;

  3.worker进程处理完成之后将输出通过同一个Socekt连接发送会Web Server。当worker进程处理完请求之后,关闭socket连接。如果没有达到为该进程设置的处理的请求数上限,则继续存在而不会消亡,等待下次的处理请求。

  3   CGI和FastCGI的不同之处

  为了清晰地说明CGI和FastCGI之间的不同,图3说明了FastCGI和CGI之间的执行步骤的不同之处。图中Individual Request代表着FastCGI的请求处理流程图,而PHP Lifespan很明显就代表着CGI处理请求的流程图。从图中可以看出相对于CGI而言FastCGI处理外部的动态请求时不用为每个请求执行PHP的MINIT(即PHP的模块初始化过程,需要加载php.ini,为php启动的第一个步骤)过程。之所以会出现这种情况,究其原因在于worker进程启动的时候这个步骤已经完成了,worker进程是常驻内存的且不止可以处理一次请求,因此只需要针对特定的请求初始化(RINIT)就可以了,也就是说不用对每次请求都加载一次php.ini。在处理完本次请求之后,如果没有到达处理请求的上限该进程也不用消亡,也就没有了后面的扩展关闭步骤。但是CGI的执行模式是为每个请求fork一个子进程,每个子进程都是重新加载配置文件,按照php执行的步骤按部就班的执行,这也就造成了直接使用CGI的代价昂贵,尤其是在高并发的情况下。

图2 CGI和FastCGI声明周期示意图

  4.   PHP FastCGI---PHP-FPM的架构实现

  PHP-FPM的进程管理方式为:存在的master进程可以管理多个pool,每个pool由master进程监听不同的端口,每个pool中又可以存在许多不同的worker进程。每个worker进程都常驻内存,并且随着请求数量的增多可以动态的增加,就是所谓的prefork动态增加;且每个worker进程都在达到最大的处理请求之后会自动重启,如果进程没有达到最大的请求数量而意外挂掉,则master会重启该worker进程。

  虽然,worker进程的数量可以随着请求数量的增加prefork动态增加,但是由于资源的有限,worker进程的数量存在一个上限---pm.max_children,达到这个上限之后,如果还有额外的请求且worker进程都处于繁忙状态,那么该请求会被master进程挂起到连接队列backlog中(默认值为511)。  

  在项目中Nginx和PHP-FPM是一种很好的解耦方式,Nginx的优势之处在于处理高并发,所有的静态界面的处理都由Nginx处理;而PHP-FPM专注于处理php请求,每个请求对应一个php的页面,这样实现了动态界面和静态界面处理的分离,减轻了Nignx的负担。  

  5.   总结

  这篇文章对CGI和FastCGI的工作方式简单的介绍,并对二者的工作方式做了简要的对比,FastCGI由于worker进程常驻内存,能够很大程度上提高并发性。最后对采用FastCGI的PHP-FPM做了简要的介绍。

CGI、FastCGI和PHP-FPM浅析的更多相关文章

  1. Nginx + CGI/FastCGI + C/Cpp

    接着上篇<Nginx安装与使用>,本篇介绍CGI/FASTCGI的原理.及如何使用C/C++编写简单的CGI/FastCGI,最后将CGI/FASTCGI部署到nginx.内容大纲如下: ...

  2. 漫谈CGI FastCGI WSGI

    作者:auxten链接:https://zhuanlan.zhihu.com/p/20054757来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. CGI(Common ...

  3. [转] Nginx + CGI/FastCGI + C/Cpp

    接着上篇<Nginx安装与使用>,本篇介绍CGI/FASTCGI的原理.及如何使用C/C++编写简单的CGI/FastCGI,最后将CGI/FASTCGI部署到nginx.内容大纲如下: ...

  4. PHP运行模式(cgi,fast-cgi,cli, ISAPI ,web模块模式)【转载】

    PHP运行模式有5钟: 1)cgi 通用网关接口(Common Gateway Interface))2)fast-cgi 常驻 (long-live) 型的 CGI3)cli  命令行运行   (C ...

  5. cgi fast-cgi php-fpm区别

    php-cli 是php在系统执行的程序,直接执行php文件: cgi和fast-cgi的区别1.cgi和fast-cgi都是php解析协议,负责解析服务器分发过来的php动态文件:cgi程序就会去解 ...

  6. 转:nginx+CGI/FASTCGI

    简介版: 1.fastcgi与cgi区别:fastcgi通过线程来响应请求,而cgi对每个请求生成一个进程. 2.典型nginx数据传输过程:user->nginx->本地socket(请 ...

  7. cgi fastcgi php-cgi php-fpm

      参考: 摘至:http://www.cnblogs.com/thinksasa/p/4497567.html 详说fastcgi,php-fpm的区别:http://segmentfault.co ...

  8. 【转】Nginx + CGI/FastCGI + C/Cpp

    接着上篇<Nginx安装与使用>,本篇介绍CGI/FASTCGI的原理.及如何使用C/C++编写简单的CGI/FastCGI,最后将CGI/FASTCGI部署到nginx.内容大纲如下: ...

  9. CGI fastCgi php-fpm PHP-CGI 辨析

    CGI fastCgi php-fpm PHP-CGI 辨析 LNMP环境中的nginx是不支持php的,需要通过fastcgi插件来处理有关php的请求.而php需要php-fpm这个组件提供该功能 ...

  10. CGI & FastCGI 协议

    目录 CGI 是什么 CGI 特点 CGI 的流程 FastCGI 是什么 CGI & FastCGI(转载) 推荐Blog: CGI是什么,FastCGI是什么 CGI 是什么 公共网关接口 ...

随机推荐

  1. Android 字体相关总结

    1.Android系统默认支持三种字体,分别为:“sans”, “serif”,  “monospace“  系统缺省方式(经试验缺省采用采用sans): 2.在Android中可以引入其他字体 3. ...

  2. Codeforces Round #157 (Div. 2)

    A. Little Elephant and Chess 模拟. B. Little Elephant and Magic Square 枚举左上角,计算其余两个位置的值,在\(3\times 3\) ...

  3. C#可扩展编程之MEF学习

    MEF系列文章: C#可扩展编程之MEF学习笔记(一):MEF简介及简单的Demo C#可扩展编程之MEF学习笔记(二):MEF的导出(Export)和导入(Import) C#可扩展编程之MEF学习 ...

  4. Install Qt creator

    download qt for linux yum install dialog move download qt file(qt-opensource-linux-x64-5.6.0.run) fr ...

  5. bootstrap初接触

    Bootstrap 是最受欢迎的 HTML.CSS 和 JS 框架.(主要是结合HTML5 CSS3的样式, 基于jquery+Bootstrap 自带 12 种 jQuery 插件,扩展了功能,可以 ...

  6. git配置管理

    生成 SSH 公钥 如前所述,许多 Git 服务器都使用 SSH 公钥进行认证. 为了向 Git 服务器提供 SSH 公钥,如果某系统用户尚未拥有密钥,必须事先为其生成一份. 这个过程在所有操作系统上 ...

  7. Delphi ActiveX Form的使用实例

    Delphi ActiveX Form的使用实例 By knityster 1. ActiveX控件简介 ActiveX控件也就是一般所说的OCX控件,它是ActiveX技术的一部分. ActiveX ...

  8. 学习SQL的点点滴滴(二)删除临时表

    select into 创建的表属于临时表,判断是否存在的方法 select c_adno,c_con_no into #temp from tb_contract IF OBJECT_ID( 'te ...

  9. coderforces719b

    题目大意:给定一个字符串,这个字符串中只有“r”和"b"组成,每次操作只能交换两个字符的位置或者将一个字符由"r"变"b"(或由" ...

  10. Hadoop I/O操作原理整理

    I/O操作中的数据检查 校验和方式是检查数据完整性的重要方式.一般会通过对比新旧校验和来确定数据情况,如果两者不同则说明数据已经损坏.比如,在传输数据前生成了一个校验和,将数据传输到目的主机时再次计算 ...