先了解一下普通cgi的工作流程:
web server收到用户请求,并把请求提交给cgi程序,cgi程序根据请求提交的参数作相应处理,然后输出标准的html语句返回给web server,web server再返回给客户端,这就是普通cgi的工作原理。
从 上面看,cgi所要实现的不过是动态网页而已,这种处理方式的特点就是每接到一个请求,web server都要fork出一个单独的cgi程序的进程来处理,这种方式的好处是把web server和具体的程序处理独立开来,结构清晰,可控性强,同时缺点就是如果在高访问需求的情况下,cgi的进程fork就会成为很大的服务器负担,想 象一下数百个并发请求导致服务器fork出数百个进程就明白了。这也是为什么cgi一直背负性能低下,高资源消耗的恶名的原因。
相应的有问题就有解决方案,目前流行的方案就是使用模块设计,基本上目前的web server都有相应的模块机制来扩充它的功能, 只要按照其设计规范设计出来的模块,就能插入到web server自身的进程处理,因此性能有很大改观,例如IIS的isapi,apache的dso。但是,这种方法也不是没有缺点的,例如对于不同的 web server,要按照不同标准开发,无法做到webserver无关性;例如这将输入验证的工作转交给了web server,没办法自由处理;例如一旦出现问题将影响整个web server处理流程;例如插入web server进程导致的无法以多用户标示运行,无法处理虚拟主机权限等。
所幸我们还有另外的选择,这就是fastcgi。 fastcgi是基于cgi架构的扩展,他的核心思想就是在web server和具体cgi程序之间建立一个智能的可持续的中间层,统管cgi程序的运行,这样web server只需要将请求提交给这个层,这个层再派生出几个可复用的cgi程序实例,然后再把请求分发给这些实例,这些实例是可控的,可持续,可复用的, 因此一方面避免了进程反复fork,另一方面又可以通过中间层的控制和探测机制来监视这些实例的运行情况,根据不同的状况fork或者回收实例,达到灵活 性和稳定性兼得的目的。
本人曾经做过测试,使用cgi方式运行php效率最差,mod_php方式性能非常不错,几乎是cgi方 式的50倍,但是无法保证虚拟主机站点的安全性隔离,而fastcgi性能则基本和mod_php相当,这还是在使用了suexec切换虚拟主机站点运行 用户的情况下的结果。
fastcgi与cgi的区别
先讲下cgi:
cgi在2000年或更早的时候用得比较多, 以前web服务器一般只处理静态的请求,如果碰到一个动态请求怎么办呢?web服务器会把根据这次请求的内容,然后会fork一个新进程运行外部c程序 (或perl脚本...), 这个进程会把处理完的数据返回给web服务器,最后web服务器把内容发送给用户,刚才fork的进程也随之退出。 如果下次用户还请求改动态脚本,那么web服务器又再次fork一个新进程,周而复始的进行。
后来出现了一种更高级的方式是, web服务器可以内置perl解释器或php解释器。 也就是说这些解释器做成模块的方式,web服务器会在启动的时候就启动这些解释器。 当有新的动态请求进来时,web服务器就是自己解析这些perl或php脚本,省得重新fork一个进程,效率提高了。
fastcgi的方式是,web服务器收到一个请求时,他不会重新fork一个进程(因为这个进程在web服务器启动时就开启了,而且不会退 出),web服务器直接把内容传递给这个进程(进程间通信,但fastcgi使用了别的方式,tcp方式通信),这个进程收到请求后进行处理,把结果返回 给web服务器,最后自己接着等待下一个请求的到来,而不是退出。
fastcgi跟cgi的区别是:
在web服务器方面 在对数据进行处理的进程方面
cgi fork一个新的进程进行处理 读取参数,处理数据,然后就结束生命期
fastcgi 用tcp方式跟远程机子上的进程或本地进程建立连接 要开启tcp端口,进入循环,等待数据的到来,处理数据
举个例子: 服务端现在有个10万个字单词, 客户每次会发来一个字符串,问以这个字符串为前缀的单词有多少个。 那么可以写一个程序,这个程序会建一棵trie树,然后每次用户请求过来时可以直接到这个trie去查找。 但是如果以cgi的方式的话,这次请求结束后这课trie也就没了,等下次再启动该进程时,又要新建一棵trie树,这样的效率就太低下了。 而用fastcgi的方式的话,这课trie树在进程启动时建立,以后就可以直接在trie树上查询指定的前缀了。
[问1]
我也是 c cgi 的坚定支持者,而且亲自试验过 FastCGI 的稳定性和高性能。但是很长时间我也没查明白:为什么现在使用 cgi 的网站那么少,FastCGI 更少了?
[答1]
你这个问题问的非常好,
都知道 CGI 只是个技术标准(目前使用的是 CGI/1.1), 因为该标准非常简单所有它很容易用各种高级语言和脚本语言进行描述; 但它也给 CGI 开发者带来了困难, 那就是过去没有非常好的开发工具以开发方便开发者开发复杂的应用. 很多时候它们不得不手工 printf 输入每一句 html 语句. 这样严重限制了传统 cgi 的发展;
与此同时, 另一批工具(暂时称之为泛 CGI吧), 如 asp, jsp, php, 它们继承了 CGI 标准的简单性, 同时提供了相应的解释或编译工具. 通过这些工具, 开发人员只要在 html/xml 模板文件中嵌入相应(脚本)语句即可, 特别是 asp.net 开发环境, php 之后的模板技术等, jsp 等 strust 框架等都为开发人员提供了更为抽象化的开发工具, 使开发人员彻底忘记了它们(asp, php, jsp等)的前身 CGI (之所以称它们为泛 CGI, 因为它们都是 CGI 技术的继承和发展者).
[问3]
php的性能是因为成了服务器的模块,但是 c cgi 也能编写成模块的模式,特别是 FastCGI 天生几乎就是服务器的模块,可是为什么用的人那么少呢?
而且我自己的试验证明,FastCGI 极稳定,不稳定基本是程序没编写好,有内存泄露、忘记重置等问题造成的.
[答3]
PHP 也可以作为 CGI 运行, 同时也支持 FastCGI.
php 性能是因为成了服务器的模块, 这导致 php 非常依赖服务器, 所以通常 php 只在 apahce 服务器具有非常好的性能, 换个 webserver 甚至它是不能运行的. 严格遵守 CGI 标准的应用工具应该是不存在这些问题的.
不过, 在适当的应用中, 为了性能牺牲一些特性为是必要的.
对 FastCGI 要有充分的信心, FastCGI 没有问题, 在很多应用中证明它都有很好的表现.
前面提及, 用的少主要原因是在 CSP/eybuild 之前大家没有很好的编写复杂应用的 CGI 开发工具.
[问4]
实际应用上,多数人会选择 apache 或 IIS ...
[答4]
WEB 服务应用领域是主要用这两个服务器, 不过其它 web 应用(如设备管理/控制等), 使用的 webserver 就很广泛了, 如 thttpd, mini-httpd, goAhead, lighttpd, boa, ...
它们可能还要运行在不同的 CPU 架构(如 inter, xscale, arm, mips, ...)下, 不同的存储器限定环境中(如只有 2M, 8M, 16M的内存) 无硬盘, 只有几M的 flash 等,
这些环境的应用中, 目前最主要的 web 开发语言都是 c, ...
[问5]
我认为随着ajax应用的普及,模板技术有逐渐被取代的趋势
[答5]
ajax 是一种非常不错客户端技术, 通在不刷新整个页面的情况下给用户带来很新体验. 它服务器端的技术互相补充相互依赖, 从目前的形式看, 还很难说谁会取代谁的趋势. 根据项目和应用不同, 开发者应该灵活选择它们要选用的开发工具和开发技术, 并进一有效的融合, 不宜单纯一味追求某一技术.
[问6]
web标准客户端的结构、表现、行为分离,确实是好框架,是发展趋势,而且能简化服务器端开发。我认为随着应用的普及,模板技术会被取代。那时候,开发服务端只要编程就可以了,完全脱离页面的束缚。
[答6]
呵呵, W3C 关于 结构、表现、行为分离 确实极大地推动了 web 技术的发展,
但它主要是指结构-(html)、表现(css)、行为(js) 三者的分离, 是一种客户端技术, 与取代模板关系不大.
一般认为 ajax 的目标把富客户端, 弱服务器, 它可能对 服务器端的模板技术有一对冲击.
1,2 C/C++本身的模板技术已经足够了。 论坛里面我写过一个模板能满足99%的cgi开发
而java的一些框架和技术,是其他产品无法或者难以替代的
3,4 错误,php比c cgi更适应各种平台。什么情况会只有2m内存,硬盘? 也只能适合嵌入式了
5.6 ajax 技术不能代替任何现有的,对google的盲目崇拜而已。ajax被用在很多不适合的地方, 大多又都带来加大服务器消耗的代价
使用FastCGI只会愈来愈少。