CGI、FastCGI、PHP-CGI与PHP-FPM的概念以及各个之间的关系

CGI、FastCGI、PHP-CGI与PHP-FPM的概念以及各个之间的关系

     在搭建 LAMP/LNMP 服务器时,会经常遇到 PHP-FPM、FastCGI和CGI 这几个概念。如果对它们一知半解,很难搭建出高性能的服务器。接下来我们就以图形方式,解释这些概念之间的关系。

    基础
    在整个网站架构中,Web Server(如Apache/Nginx)只是内容的分发者。举个栗子,如果客户端请求的是 index.html,那么Web Server会去文件系统中找到这个文件,发送给浏览器,这里分发的是静态数据。如下图:

     

 

     如果请求的是 index.php,根据配置文件,Web Server知道这个不是静态文件,需要去找 PHP 解析器来处理,那么他会把这个请求简单处理,然后交给PHP解析器。

 

      当Web Server收到 index.php 这个请求后,会启动对应的 CGI 程序,这里就是PHP的解析器(PHP-CGI)。接下来PHP解析器会解析php.ini文件,初始化执行环境然后处理请求,再以CGI规定的格式返回处理后的结果,退出进程,Web server再把结果返回给浏览器。这就是一个完整的动态PHP Web访问流程,接下来再引出这些概念,就好理解多了。

    概念初识

    CGI:是 Web Server 与 Web Application 之间数据交换的一种协议。

    FastCGI:同 CGI,是一种通信协议,但比 CGI 在效率上做了一些优化。同样,SCGI 协议与 FastCGI 类似。

    PHP-CGI:是 PHP (Web Application)对 Web Server 提供的 CGI 协议的接口程序。

    PHP-FPM:是 PHP(Web Application)对 Web Server 提供的 FastCGI 协议的接口程序,额外还提供了相对智能的一些任务管理。

    补充:可以说php-fpm不仅仅是用来在web server 和 php之间通信的fastCGI接口程序。同样还是php的进程池管理工具

   Web Server :一般指Apache、Nginx、IIS、Lighttpd、Tomcat等服务器,

   Web Application :一般指PHP、Java、Asp.net等应用程序。

    一、CGI

    1、概念

    CGI全称是“公共网关接口”(Common Gateway Interface),HTTP服务器与你的或其它机器上的程序进行“交谈”的一种工具,其程序须运行在网络服务器上。

    CGI可以用任何一种语言编写,只要这种语言具有标准输入、输出和环境变量。如php,perl,tcl等。

    2、工作原理

    CGI就是专门用来和 web 服务器打交道的。web服务器收到用户请求,就会把请求提交给cgi程序(如php-cgi),cgi程序根据请求提交的参数作应处理(解析php),然后输出标准的html语句,返回给web服服务器,WEB服务器再返回给客户端,这就是普通cgi的工作原理。

    3、缺点

    每一次web请求都会有启动和退出过程,也就是每次都要花费时间去fork一次(这是CGI最为人诟病的fork-and-execute 模式),这样一来在大规模并发下,就会挂掉。

    二、FastCGI

    1、概念

    Fastcgi是CGI的升级版,也是一种通信协议,它是用来提高CGI程序性能的。

    2、特点

    Fastcgi的特点是会在一个进程中依次完成多个请求,以达到提高效率的目的,大多数Fastcgi实现都会维护一个进程池。

    3、工作原理

    

      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子进程接着等待并处理来自进程管理器(运行在Web Server中)的下一个连接。 在CGI模式中,php-cgi在此便退出了

     FASTCGI与CGI的区别:

     在上述情况中,你可以想象CGI通常有多慢。每一个Web请求PHP都必须重新解析php.ini、重新载入全部扩展并重新初始化全部数据结构。

     使用FastCGI,所有这些都只在进程启动时发生一次。一个额外的好处是,持续数据库连接(Persistent database connection)可以工作。

     4、FastCGI对进程的管理

     FastCGI会先启动一个master,解析配置文件,初始化执行环境,然后再启动多个worker。当请求过来时,master会传递给一个worker,然后立即可以接受下一个请求。这样就避免了重复的劳动,效率自然是高。而且当worker不够用时,master可以根据配置预先启动几个worker等着;当然空闲worker太多时,也会停掉一些,这样就提高了性能,也节约了资源。

    三、PHP-CGI

    PHP-CGI是PHP自带的FastCGI管理器。它是php的解释器。

    PHP-CGI只是个CGI程序,他自己本身只能解析请求,返回结果,不会进程管理(皇上,臣妾真的做不到啊!)

    PHP-CGI的不足:

    1、php-cgi变更php.ini配置后需重启php-cgi才能让新的php-ini生效,不可以平滑重启直接杀死php-cgi进程,php就不能运行了。(PHP-FPM和Spawn-FCGI就没有这个问题,守护进程会平滑重启生成新的子进程。)

    2、不支持动态worker调度,只能一开始指定要起几个worker

    四、PHP-FPM

    1、概念

    PHP-fpm是针对于PHP的,Fastcgi的一种实现,他负责管理一个进程池,处理来自Web服务器的请求。目前,PHP-fpm是内置于PHP的

    fastcgi是一个协议,php-fpm实现了这个协议

    五、 php-fpm与php-cgi的区别

    最初php-fpm是需要调用php-cgi来解释php代码的,php-fpm只起到进程管理的作用,但是因为php-fpm这个民间第三方写的工具实在比php-cgi好太多了,php官方在php5.4时就把它集成到了php官方发布的包中,并且php-fpm不需要再依赖php-cgi,直接把php解释器的功能集成进php-fpm了

    注意:win不支持php-fpm,因为php-fpm是使用Linux的fork()来做的,所以win下面基本上还是使用php-cgi,当然有人用“Cygwin”这个软件可以在win下模拟Linux的fork(),但如果你是本地开发环境就没必要这么做了,用win10做开发的我建议你们考虑一下wsl。

    六、比喻

    在网上看到有人做了一个很形象的比喻,虽然不全面,但是非常适合新手入门,去理解CGI、FastCGI、PHP-CGI与PHP-FPM之间的关系:

    你(PHP)去和爱斯基摩人(web服务器,如 Apache、Nginx)谈生意

    你说中文(PHP代码),他说爱斯基摩语(C代码),互相听不懂,怎么办?那就都把各自说的话转换成英语(FastCGI 协议)吧。

    怎么转换呢?你就要使用一个翻译机(PHP-FPM)(当然对方也有一个翻译机,那个是他自带的)。我们这个翻译机是最新型的,老式的那个(PHP-CGI)被淘汰了。不过它(PHP-FPM)只有年轻人(Linux系统)会用,老头子们(Windows系统)不会摆弄它,只好继续用老式的那个。

 

总结

    最后,我们来总结一下,这些技术经过不断的升级,可以解决什么问题(不然也不会升级嘛)。

   所以,如果要搭建一个高性能的PHP WEB服务器,目前最佳的方式是Apache/Nginx + FastCGI + PHP-FPM(+PHP-CGI)方式了,不要再使用 Module加载或者 CGI 方式啦

 

   参考链接:

   https://segmentfault.com/q/1010000000256516
   http://www.nowamagic.net/librarys/veda/detail/1319
   https://www.awaimai.com/371.html
   https://www.jianshu.com/p/64e52f6f4837
   http://rango.swoole.com/

 


每次都要花费时间去fork一次(这是CGI最为人诟病的fork-and-execute 模式)

posted @ 2020-07-31 10:11  欢乐豆123  阅读(602)  评论(1编辑  收藏  举报