1.通用的web架构模型以及CGI/FastCGI的由来
通用的web架构包括浏览器、web服务器、业务应用程序三个部分。浏览器发起HTTP请求;web服务器接收浏览器的HTTP请求,并将请求路由转发给对应的应用程序;业务应用程序接收web-server的请求,并完成逻辑的处理,并将处理结果返回给web服务器。
在上图中,web服务器收到客户端A的请求,根据URI将其通过 API 发送给一个数码摄相机应用程序。将得到的图片绑定到一条HTTP 响应报文中,再回送给客户端,在客户端的浏览器中显示。客户端B 的 URI 请求的是一个电子商务应用程序。客户端 B 的请求是通过服务器网关API发送给电子商务软件的,结果会被回送给浏览器。电子商务软件与客户端进行交互,引导用户通过一系列HTML页面来完成购物。如果客户端请求的静态资源,比如html静态页面,jpg图片等,那么web服务器直接将静态资源返回给浏览器。
在上面的web服务器和业务应用程序的交互过程中,需要用一种规范约定二者的传递的信息的参数,而CGI/FastCGI就是这样的规范,它需要web应用器和业务应用程序都遵循并实现这个规范。也就是说CGI和FastCGI是一种和具体编程语言无关的协议。在实际中,CGI/FastCGI协议在不同的编程语言(PHP/C/Perl/Python等),甚至是同一种编程语言中都有很多的具体实现。
2.CGI
CGI,Common Gateway Interface,中文翻译为公共网关接口,定义了网站服务器与外部内容协商程序之间交互的标准。
在CGI中,服务器对于每一次请求,都会触发一个CGI应用程序。当CGI应用程序处理完后,该进程的生命周期就结束了。在多请求并发时,就会同时存在很多的CGI应用程序在执行。
以一个例子来说服务器和CGI程序的交互过程:
如上图所示,本次请求的流程如下:
a)客户端访问 http://127.0.0.1:9003/cgi-bin/user?id=1
b)127.0.0.1 上监听 9003 端口的守护进程接受到该请求
c)通过解析 HTTP 头信息,得知是 GET 请求,并且请求的是 /cgi-bin/目录下的 user 文件。
d)将 uri 里的 id=1 通过存入 QUERY_STRING 环境变量。
e)Web 守护进程 fork 一个子进程,然后在子进程中执行 user程序,通过环境变量获取到id。
f)执行完毕之后,将结果通过标准输出返回到子进程。
g)子进程将结果返回给客户端。
备注:从例子可以知道CGI程序是被服务器采用的fork-and-execute模式来执行的。
学习资料来源于:
http://www.php-internals.com/book/?p=chapt02/02-02-03-fastcgi
3.FastCGI
CGI协议规定中,会为每条CGI 请求引发一个新进程的开销是很高的,会限制那些使用CGI的服务器的性能,并且会加重服务端机器资源的负担。为了解决这个问题,人们开发了一种新型CGI——并将其恰当地称为快速CGI,即FastCGI。这个接口模拟了CGI,但它是作为持久守护进程运行的,消除了为每个请求建立或拆除新进程所带来的性能损耗。
FastCGI是Web服务器和处理程序之间通信的一种协议, 是CGI的一种改进方案。正是因为他只是一个通信协议,因此它支持分布式的结构,所以 FastCGI程序可以在网站服务器以外的主机上执行,并且可以接受来自其它网站服务器的请求。
以一个具体的例子来说明FastCGI的工作过程:
FastCGI 与传统 CGI 模式的区别之一则是 Web 服务器不是直接执行 CGI 程序了,而是通过 Socket 与 FastCGI响应器(FastCGI 进程管理器)进行交互,也正是由于 FastCGI 进程管理器是基于 Socket 通信的,所以也是分布式的,Web 服务器可以和CGI 响应器服务器分开部署。Web 服务器需要将数据 CGI/1.1 的规范封装在遵循 FastCGI 协议包中发送给 FastCGI 响应器程序。
学习资料来源于:
http://www.php-internals.com/book/?p=chapt02/02-02-03-fastcgi