前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >全面了解CGI、FastCGI、PHP-FPM

全面了解CGI、FastCGI、PHP-FPM

作者头像
猿哥
发布2019-11-13 15:10:04
2.7K0
发布2019-11-13 15:10:04
举报
文章被收录于专栏:Web技术布道师

一、抛个砖

1、Web Server传递数据的方法

正式说CGI之前,先来了解一下Web Server传递数据的另外一种方法:PHP Module加载方式。相信都会想起Apache吧,初学php时,在windows上安装完php和Apache之后,为了让Apache能够解析php代码,我们会在Apache的配置文件(httpd.conf)中添加如下配置:

代码语言:javascript
复制
#添加下边两行
LoadModule php5_module D:/php/php5apache2_2.dll
AddType application/x-httpd-php .php
# 修改如下内容
<IfModule dir_module>
    DirectoryIndex index.php index.html
</IfModule>

当在linux环境下源码安装时,大致是这样:

代码语言:javascript
复制
# ./configure --with-mysql=/usr/local --with-apache=/usr/local/apache --enable-track-vars

其实原理都是,用LoadModule来加载php5_module,就是把php作为apache的一个子模块来运行。当通过web访问php文件时,apache就会调用php5_module来解析php代码。

那么,php5_module是如何将数据传给php的解析器来解析php代码的呢? 答案是:sapi

用一张图来看apache、php、sapi三者之间的关系:

从上面图中,我们看出了sapi就是这样的一个中间过程,sapi提供了一个和外部通信的接口,使得PHP可以和其他应用进行交互数据(apache,nginx等)。php默认提供了很多种sapi,常见的提供给apache和nginx的php5_module、CGI、FastCGI,给IIS的ISAPI,以及Shell的CLI。(httpd是Apache超文本传输协议(HTTP)服务器的主程序。被设计为一个独立运行的后台进程,它会建立一个处理请求的子进程或线程池)

所以,以上的apache调用php执行的过程如下:

代码语言:javascript
复制
apache -> httpd -> php5_module -> sapi -> php

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

在上图中,我们很清晰的可以看到,apache每接收一个请求,都会产生一个进程来连接php通过sapi来完成请求,可想而知,如果一旦用户过多,并发数过多,服务器就会承受不住了。而且,把php当做一个模块加载到apache中,出问题时很难定位是php的问题还是apache的问题。

2、引出概念

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

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

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

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

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

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

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

(Web Server 一般指Apache、Nginx、IIS、Tomcat等服务器,Web Application 一般指PHP、Java、Asp.net等应用程序)

二、概念

1、CGI

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

WEB服务器会传哪些数据给PHP解析器呢?URL、查询字符串、POST数据、HTTP header都会有。所以,CGI就是规定要传哪些数据,以什么样的格式传递给后方处理这个请求的协议。也就是说,CGI就是专门用来和 web 服务器打交道的。web服务器收到用户请求,就会把请求提交给cgi程序(如php-cgi),cgi程序根据请求提交的参数作应处理(解析php),然后输出标准的html语句,返回给web服服务器,WEB服务器再返回给客户端,这就是普通cgi的工作原理。(cgi程序,你就可以理解成遵循cgi协议编写的程序)

优点:

CGI的好处就是完全独立于任何服务器,仅仅是做为中间分子。提供接口给web服务器和web应用(如提nginx和php)。他们通过cgi搭线来完成数据传递。这样做的好处了尽量减少2个的关联,使他们2变得更独立。

缺点:

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

2、FastCGI

从根本上来说,FastCGI是用来提高CGI程序性能的。类似于CGI,FastCGI也可以说是一种协议。

FastCGI像是一个常驻(long-live)型的CGI,它可以一直执行着,只要激活后,不会每次都要花费时间去fork一次。

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

举例:

当web server收到/index.php请求,看一下CGI程序和FastCGI程序分别是怎么处理的:

CGI:当收到web server请求后,会启动对应的CGI程序,这里就是PHP的解析器(php-cgi)。接下来PHP解析器会解析php.ini文件,初始化执行环境,然后处理请求,再以规定的CGI规定的格式返回处理后的结果,退出进程。(CGI每次接收到请求都会执行这些步骤)

FastCGI:首先,FastCGI程序会先启动一个master,解析配置环境,初始化执行环境,然后再启动多个worker。当请求过来时,master会传递给一个worker,然后立即可以接受下一个请求。这样就避免了重复的劳动,效率自然是高。而且当worker不够用时,master可以根据配置预先启动几个worker等着;当然空闲worker太多时,也会停掉一些,这样就提高了性能,也节约了资源,这就是fastcgi对进程的管理。(CGI程序和FastCGI程序,可以理解成遵循CGI协议和FastCGI协议编写的程序)

FastCGI的工作原理:

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

(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在此便退出了。

CGI与FastCGI比较:

(1)对于CGI来说,每一个Web请求PHP都必须重新解析php.ini、重新载入全部扩展,并重新初始化全部数据结构。而使用FastCGI,所有这些都只在进程启动时发生一次。一个额外的好处是,持续数据库连接(Persistent database connection)可以工作。

(2)由于FastCGI是多进程,所以比CGI多线程消耗更多的服务器内存,php-cgi解释器每进程消耗7至25兆内存,将这个数字乘以50或100就是很大的内存数。

3、PHP-FPM

首先要说的是:fastcgi是一个协议,php-fpm实现了这个协议。

大家都知道,PHP的解释器是php-cgi。php-cgi只是个CGI程序,他自己本身只能解析请求,返回结果,不会进程管理,所以就出现了一些能够调度php-cgi进程的程序,php-fpm就是这样的一个东西。它克服了php-cgi变更php.ini配置后,需重启php-cgi才能让新的php-ini生效,不可以平滑重启,直接杀死php-cgi进程,php就不能运行了的问题。修改php.ini之后,php-cgi进程的确没办法平滑重启的。php-fpm对此的处理机制是新的worker用新的配置,已经存在的worker处理完手上的活就可以歇着了,通过这种机制来平滑过度。

php-fpm提供了更好的php进程管理方式,可以有效的控制内存和进程,可以平滑重载php配置。

总结一下这个升级的过程:

如果要搭建一个高性能的PHP WEB服务器,目前最佳的方式是Apache/Nginx + FastCGI + PHP-FPM(+PHP-CGI)方式了。

参考:

https://segmentfault.com/a/1190000010968145

https://www.awaimai.com/371.html

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-11-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 PHP技术大全 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档