Fast CGI 工作原理

CGI的历史

    早期的webserver只处理html等静态文件,但是随着技术的发展,出现了像php等动态语言。 

    webserver处理不了了,怎么办呢?那就交给php解释器来处理吧! 

    交给php解释器处理很好,但是,php解释器如何与webserver进行通信呢?

    为了解决不同的语言解释器(如php、python解释器)与webserver的通信,于是出现了cgi协议。只要你按照cgi协议去编写程序,就能实现语言解释器与webwerver的通信。如php-cgi程序。

FastCGI的改进

    有了cgi协议,解决了php解释器与webserver通信的问题,webserver终于可以处理动态语言了。但是,webserver每收到一个请求,都会去fork一个cgi进程,请求结束再kill掉这个进程。这样有10000个请求,就需要fork、kill php-cgi进程10000次。

    有没有发现很浪费资源?

    于是,出现了cgi的改良版本,fast-cgi。fast-cgi每次处理完请求后,不会kill掉这个进程,而是保留这个进程,使这个进程可以一次处理多个请求。这样每次就不用重新fork一个进程了,大大提高了效率。

PHP-FPM是什么

        php-fpm即php-Fastcgi Process Manager. 

        php-fpm是 FastCGI 的实现,并提供了进程管理的功能。 

        进程包含 master 进程和 worker 进程两种进程。 

        master 进程只有一个,负责监听端口,接收来自 Web Server 的请求,而 worker 进程则一般有多个(具体数量根据实际需要配置),每个进程内部都嵌入了一个 PHP 解释器,是 PHP 代码真正执行的地方。

FastCGI是什么?

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

        FastCGI的官方站点在http://www.fastcgi.com

FastCGI的工作原理是

        1、Web Server 启动时载入FastCGI进程管理器(IIS ISAPI或Apache Module,nginx 下 fastcgi 与服务器是分离的,fastcgi 可有 lighttpd 下的spawan-cgi或者 php-fpm 来管理));

        2、FastCGI进程管理器自身初始化,启动多个CGI解释器进程 (在任务管理器中可见多个php-cgi.exe)并等待来自Web Server的连接。

        3、当客户端请求到达Web Server时,FastCGI进程管理器选择并连接到一个CGI解释器。Web server将CGI环境变量和标准输入发送到FastCGI子进程php-cgi.exe。

        4、FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回Web Server。当FastCGI子进程关闭连接时,请求便告处理完成。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在WebServer中)的下一个连接。 在正常的CGI模式中,php-cgi.exe在此便退出了。

        在上述情况中,你可以想象CGI通常有多慢。每一个Web请求PHP都必须重新解析php.ini、重新载入全部dll扩展并重初始化全部数据结构。使用FastCGI,所有这些都只在进程启动时发生一次。一个额外的好处是,持续数据库连接(Persistent database connection)可以工作。

总结

        nginx与php-fpm的结合,完整的流程是这样的:

 
 

为什么要使用FastCGI,而不是多线程CGI解释器?

        这可能出于多方面的考虑,例如:

        1、你无论如何也不能在windows平台上稳定的使用多线程CGI解释器,无论是IIS ISAPI方式还是APACHE Module方式,它们总是运行一段时间就崩溃了。奇怪么?但是确实存在这样的情况!当然,也有很多时候你能够稳定的使用多线程CGI解释器,但是,你有可能发现网页有时候会出现错误,无论如何也找不到原因,而换用FastCGI方式时这种错误的概率会大大的降低。我也不清楚这是为什么,我想独立地址空间的CGI解释器可能终究比共享地址空间的形式来得稳定一点点。

        2、性能!性能?可能么,难道FastCGI比多线程CGI解释器更快?但有时候确实是这样,只有测试一下你的网站,才能最后下结论。原因嘛,我觉得很难讲,但有资料说在Zend WinEnabler的时代,Zend原来也是建议在Windows平台下使用FastCGI而不是IIS ISAPI或Apache Module,不过现在Zend已经不做这个产品了。

FastCGI的技术原理

        如果想了解FastCGI的技术原理就要了解何为”短生存期应用程序”,何为”长生存期应用程序”。

        先从CGI技术开刀,以下是CGI技术的理论:每次当客户请求一个CGI的时候,Web服务器就请求操作系统生成一个新的CGI进程。当CGI满足要求后,服务器就杀死这个进程。服务器对客户端的每个请求都要重复这样的过程。

        而FastCGI技术的理论为:FastCGI程序一旦产生后,他可以持续工作,足够满足客户的请求直到被明确的终止。如果你希望通过协同处理来提高程序的性能,你可以请求Web服务器运行多个FastCGI 应用程序的副本。

        CGI就是所谓的短生存期应用程序,FastCGI就是所谓的长生存期应用程序。

        由于FastCGI程序并不需要不断的产生新进程,可以大大降低服务器的压力。并且产生较高的应用效率。

        自今,较为流行的Java语言Servlet技术在设计上是以参考FastCGI的技术运行所设计。

FastCGI的特点

        1. 打破传统页面处理技术

                传统的页面处理技术,程序必须与Web服务器或Application服务器处于同一台服务器中。这种历史已经早N年被FastCGI技术所打破, FastCGI技术的应用程序可以被安装在服务器群中的任何一台服务器,而通过TCP/IP协议与Web服务器通讯,这样做既适合开发大型分布式Web 群,也适合高效数据库控制。

        2. 明确的请求模式

                CGI技术没有一个明确的角色,在FastCGI程序中,程序被赋予明确的角色(响应器角色、认证器角色、过滤器角色)。

        3. 合理的程序结构

                起初,真的很讨厌FastCGI应用程序的结构要求。没关系,您经过一段时间编写后就会喜欢这种结构,只有这种完全规范的结构才能让您的程序更有效率。

Fastcgi到底是什么样的技术

        注:本人对LAMP,python了解不是很多,此文是我的个人理解,如果有误忘告知

        自从接触rubyonrails以来,fastcgi这个技术标准就进入了我的视线,从技术角度看,fastcgi的优点还是很多的,作为一种替代cgi的技术标准, fastcgi有如下优点(稳定,安全,高性能,方便扩展)

        从稳定性上看, fastcgi是以独立的进程池运行来cgi,单独一个进程死掉,系统可以很轻易的丢弃,然后重新分配新的进程来运行逻辑.

        从安全性上看, fastcgi和宿主的server完全独立, fastcgi怎么down也不会把server搞垮,        

        从性能上看, fastcgi把动态逻辑的处理从server中分离出来, 大负荷的IO处理还是留给宿主server, 这样宿主server可以一心一意作IO,对于一个普通的动态网页来说, 逻辑处理可能只有一小部分, 大量的图片等静态IO处理完全不需要逻辑程序的参与(注1)

        从扩展性上讲, fastcgi是一个中立的技术标准, 完全可以支持任何语言写的处理程序(php,java,python…)

        但是让我感到迷惑不解的是,apache对fastcgi的支持mod_fastcgi简直就是一塌糊涂, 最新的稳定版本居然还是2003年的,snap也只到2004年, 在1.3下面还勉强可以用, 在apache2.0上更是被报告无法稳定运行.fastcgi在[lighttpd][]上表现还算不错, 但是lighttpd在用户群,兼容性上还不够主流(也就在linux上面表现不错, 没有正式的windows版本, solaris下面也有bug). 另外fastcgi也缺乏发展,让人有被废弃掉了的感觉.(ruby的dbi也是这个状况). 和其他日新月异的技术标准比, fastcgi地位尴尬

        直到我看到这篇文章才明白,fastcgi真是的命苦.(呵呵,以下的内容取自该文章)

        从名字上看fastcgi是fast的cgi的,属于改良派.从理论上,他可以很多程序语言接口来开发动态web,但是这些程序语言每一个都是走完全革命的道路. java阵营就自己搞了一套j2ee server标准,要协作也直接找apache或者IIS谈,瞧不上fastcgi. aspx直接和IIS是亲兄弟,没有fastcgi的份. 剩下的php因为太流行(LAMP),和apache是铁哥们,一个mod_php就解决了,简单方便, python社区的牛人太多,精力旺盛,人家搞了个SCGI玩,和fastcgi比是有过之而无不及. 等到rails出山的时候, fastcgi真的算是老态龙钟了.

        rails的出现使得fastcgi重新焕发了青春, apache也开始重新构建新的mod_proxy_fcgi,但是它的前途还不能说是一片光明, 我觉得至少有以下几个问题

        目前的fastcgi和server沟通还不够智能,一个fastcgi进程如果执行时间过长会被当成是死进程杀掉重起,这样在处理长时间任务的时候很麻烦.这样做也使得fastcgi无法允许联机调试.

        SCGI等类似技术的都可以替换fastcgi, SCGI在python中很成功,功能完备,目前SCGI也开始支持rails了

        随着rails的流行,一个独立的mod_rails是可能出现的,而且ruby自身的webserver也开始涌现,以后极有可能自己搞一套东西连接主流的webserver.fastcgi设计的时候是想作common gateway interface(cgi)的,但是这个目标的现在看来已经不适合了

        总结: 我觉得fastcgi的前途不明朗, 但是目前来说,他也是rails唯一可以进入生产环境的工具,只用搞懂怎么配就可以了,没有必要深入研究.

        注1: 有时候逻辑也会参与图片的生成,这时候图片的IO处理就需要动态程序介入了,此时fastcgi技术上的优势虽然体现不出来,但是也不会比其他技术标准差.

cgi、fast-cgi协议

cgi的历史

早期的webserver只处理html等静态文件,但是随着技术的发展,出现了像php等动态语言。 

webserver处理不了了,怎么办呢?那就交给php解释器来处理吧! 

交给php解释器处理很好,但是,php解释器如何与webserver进行通信呢?

为了解决不同的语言解释器(如php、python解释器)与webserver的通信,于是出现了cgi协议。只要你按照cgi协议去编写程序,就能实现语言解释器与webwerver的通信。如php-cgi程序。

 
 

链接:https://www.jianshu.com/p/415b83972795

原文地址:https://www.cnblogs.com/xiangshihua/p/13277038.html