php-fpm cgi fast-cgi

基础

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

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

当Web Server收到 index.php 这个请求后,会启动对应的 CGI 程序,这里就是PHP的解析器。接下来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 协议的接口程序,额外还提供了相对智能一些任务管理。

WEB 中,mysql

  • Web Server 通常指Apache、Nginx、IIS、Lighttpd、Tomcat等服务器,
  • Web Application 通常指PHP、Java、Asp.net等应用程序。

Module方式

在了解 CGI 以前,咱们先了解一下Web server 传递数据的另一种方法:PHP Module加载方式。以 Apache 为例,在PHP Module方式中,是否是在 Apache 的配置文件 httpd.conf 中加上这样几句:linux

# 加入如下2句
LoadModule php5_module D:/php/php5apache2_2.dll AddType application/x-httpd-php .php # 修改以下内容 <IfModule dir_module> DirectoryIndex index.php index.html </IfModule>

上面是 Windows 下安装php和apache环境后手动配置,在linux下源码安装大体是这样配置的:nginx

# ./configure --with-mysql=/usr/local --with-apache=/usr/local/apache --enable-track-vars

因此,这种方式,他们的共同本质都是用 LoadModule 来加载 php5_module,就是把php做为apache的一个子模块来运行。当经过web访问php文件时,apache就会调用php5_module来解析php代码。web

那么php5_module是怎么来将数据传给php解析器来解析php代码的呢?答案是经过sapi。sql

咱们再来看一张图,详细的说说apache 与 php 与 sapi的关系:数据库

mode_php

从上面图中,咱们看出了sapi就是这样的一个中间过程,SAPI提供了一个和外部通讯的接口,有点相似于socket,使得PHP能够和其余应用进行交互数据(apache,nginx等)。php默认提供了不少种SAPI,常见的提供给apache和nginx的php5_module、CGI、FastCGI,给IIS的ISAPI,以及Shell的CLI。apache

因此,以上的apache调用php执行的过程以下:

apache -> httpd -> php5_module -> sapi -> php

好了。apache与php经过php5_module的方式就搞清楚了吧!

这种模式将php模块安装到apache中,因此每一次apache结束请求,都会产生一条进程,这个进程就完整的包括php的各类运算计算等操做。

在上图中,咱们很清晰的能够看到,apache每接收一个请求,都会产生一个进程来链接php经过sapi来完成请求,可想而知,若是一旦用户过多,并发数过多,服务器就会承受不住了。

并且,把mod_php编进apache时,出问题时很难定位是php的问题仍是apache的问题。

CGI

CGI(Common Gateway Interface)全称是“通用网关接口”,WEB 服务器与PHP应用进行“交谈”的一种工具,其程序须运行在网络服务器上。CGI能够用任何一种语言编写,只要这种语言具备标准输入、输出和环境变量。如php、perl、tcl等。

WEB服务器会传哪些数据给PHP解析器呢?URL、查询字符串、POST数据、HTTP header都会有。因此,CGI就是规定要传哪些数据,以什么样的格式传递给后方处理这个请求的协议。仔细想一想,你在PHP代码中使用的用户从哪里来的。

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

CGI的好处就是彻底独立于任何服务器,仅仅是作为中间分子。提供接口给apache和php。他们经过cgi搭线来完成数据传递。这样作的好处了尽可能减小2个的关联,使他们2变得更独立。

可是CGI有个蛋疼的地方,就是每一次web请求都会有启动和退出过程,也就是最为人诟病的fork-and-execute模式,这样一在大规模并发下,就死翘翘了。

FastCGI介绍

FastCGI简单介绍

从根本上来讲,FastCGI是用来提升CGI程序性能的。相似于CGI,FastCGI也能够说是一种协议

FastCGI像是一个常驻(long-live)型的CGI,它能够一直执行着,只要激活后,不会每次都要花费时间去fork一次。它还支持分布式的运算, 即 FastCGI 程序能够在网站服务器之外的主机上执行,而且接受来自其它网站服务器来的请求。

FastCGI是语言无关的、可伸缩架构的CGI开放扩展,其主要行为是将CGI解释器进程保持在内存中,并所以得到较高的性能。众所周知,CGI解释器的反复加载是CGI性能低下的主要缘由,若是CGI解释器保持在内存中,并接受FastCGI进程管理器调度,则能够提供良好的性能、伸缩性、Fail- Over特性等等。

FastCGI的工做原理

FastCGI接口方式采用C/S结构,能够将HTTP服务器和脚本解析服务器分开,同时在脚本解析服务器上启动一个或者多个脚本解析守护进程。当HTTP服务器每次遇到动态程序时,能够将其直接交付给FastCGI进程来执行,而后将获得的结果返回给浏览器。这种方式可让HTTP服务器专注地处理静态请求,或者将动态脚本服务器的结果返回给客户端,这在很大程度上提升了整个应用系统的性能。

fastcgi

  1. Web Server启动时载入FastCGI进程管理器(Apache Module或IIS ISAPI等)
  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在此便退出了。

FastCGI与CGI特色:

  1. 对于CGI来讲,每个Web请求PHP都必须从新解析php.ini、从新载入所有扩展,并从新初始化所有数据结构。而使用FastCGI,全部这些都只在进程启动时发生一次。一个额外的好处是,持续数据库链接(Persistent database connection)能够工做。
  2. 因为FastCGI是多进程,因此比CGI多线程消耗更多的服务器内存,php-cgi解释器每进程消耗7至25兆内存,将这个数字乘以50或100就是很大的内存数。

PHP-FPM介绍

要了解PHP-FPM,就得先说说PHP-CGI。

PHP-CGI就是PHP实现的自带的FastCGI管理器。 虽然是php官方出品,可是这丫的却一点也不给力,性能太差,并且也很麻烦不人性化,主要体如今:

  1. php-cgi变动php.ini配置后,需重启php-cgi才能让新的php-ini生效,不能够平滑重启。
  2. 直接杀死php-cgi进程,php就不能运行了。

上面2个问题,一直让不少人病垢了好久,因此不少人一直仍是在用 Module 方式。 直到 2004年一个叫 Andrei Nigmatulin的屌丝发明了PHP-FPM ,这神器的出现就完全打破了这种局面,这是一个PHP专用的 fastcgi 管理器,它很爽的克服了上面2个问题,并且,还表如今其余方面更表现强劲。

也就是说,PHP-FPM 是对于 FastCGI 协议的具体实现,他负责管理一个进程池,来处理来自Web服务器的请求。目前,PHP5.3版本以后,PHP-FPM是内置于PHP的

由于PHP-CGI只是个CGI程序,他本身自己只能解析请求,返回结果,不会进程管理。因此就出现了一些可以调度 php-cgi 进程的程序,好比说由lighthttpd分离出来的spawn-fcgi。一样,PHP-FPM也是用于调度管理PHP解析器php-cgi的管理程序。

PHP-FPM经过生成新的子进程能够实现php.ini修改后的平滑重启。

总结

最后,咱们来总结一下,这些技术通过不断的升级,能够解决什么问题(否则也不会升级嘛)。

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

(cite:https://www.awaimai.com/371.html)

 

CGI:


CGI的英文是(COMMON GATEWAY INTERFACE)公共网关接口,它的做用就是帮助服务器与语言通讯,这里就是nginx和php进行通讯,由于nginx和php的语言不通,所以须要一个沟通转换的过程,而CGI就是这个沟通的协议。


nginx服务器在接受到浏览器传递过来的数据后,若是请求的是静态的页面或者图片等无需动态处理的则会直接根据请求的url找到其位置而后返回给浏览器,这里无需php参与,可是若是是一个动态的页面请求,这个时候nginx就必须与php通讯,这个时候就会须要用到cgi协议,将请求数据转换成php能理解的信息,而后php根据这些信息返回的信息也要经过cgi协议转换成nginx能够理解的信息,最后nginx接到这些信息再返回给浏览器。


fast-cgi:


传统的cgi协议在每次链接请求时,会开启一个进程进行处理,处理完毕会关闭该进程,所以下次链接,又要再次开启一个进程进行处理,所以有多少个链接就有多少个cgi进程,这也就是为何传统的cgi会显得缓慢的缘由,所以过多的进程会消耗资源和内存。


而fast-cgi则是一个进程能够处理多个请求,和上面的cgi协议彻底不同,cgi是一个进程只能处理一个请求,这样就会致使大量的cgi程序,所以会给服务器带来负担。


php-cgi:


php-cgi是php提供给web serve也就是http前端服务器的cgi协议接口程序,当每次接到http前端服务器的请求都会开启一个php-cgi进程进行处理,并且开启的php-cgi的过程当中会先要重载配置,数据结构以及初始化运行环境,若是更新了php配置,那么就须要重启php-cgi才能生效,例如phpstudy就是这种状况。


php-fpm:


php-fpm是php提供给web serve也就是http前端服务器的fastcgi协议接口程序,它不会像php-cgi同样每次链接都会从新开启一个进程,处理完请求又关闭这个进程,而是容许一个进程对多个链接进行处理,而不会当即关闭这个进程,而是会接着处理下一个链接。它能够说是php-cgi的一个管理程序,是对php-cgi的改进。


php-fpm会开启多个php-cgi程序,而且php-fpm常驻内存,每次web serve服务器发送链接过来的时候,php-fpm将链接信息分配给下面其中的一个子程序php-cgi进行处理,处理完毕这个php-cgi并不会关闭,而是继续等待下一个链接,这也是fast-cgi加速的原理,可是因为php-fpm是多进程的,而一个php-cgi基本消耗7-25M内存,所以若是链接过多就会致使内存消耗过大,引起一些问题,例如nginx里的502错误。


同时php-fpm还附带一些其余的功能:


例如平滑过渡配置更改,普通的php-cgi在每次更改配置后,须要从新启动才能初始化新的配置,而php-fpm是不须要,php-fpm分将新的链接发送给新的子程序php-cgi,这个时候加载的是新的配置,而原先正在运行的php-cgi仍是使用的原先的配置,等到这个链接后下一次链接的时候会使用新的配置初始化,这就是平滑过渡。


可能上面文字叙述很难理解,下面用图形来简要的说明浏览器请求web服务器的过程、cgi以及fastcgi,以及php-cgi和php-fpm之间的区别和联系:



上面是使用php-fpm的动态页面的过程,下面补充没有普通cgi协议的状况;
这里的web server能够是nginx,也能够是IIS和apache等http服务器,也能够成为网站服务器或者前端服务器。--------------------- 做者:贝伦酱 来源:CSDN 原文:https://blog.csdn.net/belen_xue/article/details/65950658 版权声明:本文为博主原创文章,转载请附上博文连接!

相关文章
相关标签/搜索