1.CGI
通用网关接口(Common Gateway Interface CGI)描述客户端和服务器程序之间传输数据的一种标准,可以让一个客户端,从网页浏览器向执行在网络服务器上的程序请求数据。
CGI具有跨平台的特性。
CGI的处理流程如下:
1.web服务器收到客户端的请求Http Request,启动CGI程序,并通过环境变量,标准输入传递数据。
2.CGI进程启动解析器,加载配置,链接其他服务器(如数据库服务器),逻辑处理等。
3.CGI进程将处理结果通过标准输出,标准错误,传递给web服务器。
4.web服务器收到CGI返回的结果,构建HttpResponse返回给客户端,并kill CGI进程。
CGI工作的缺点
web服务器与CGI通过环境变量,标准输入,标准输出,标准错误互相传递数据。在遇到用户连接请求:
1.先fork CGI子进程,然后该子进程处理请求,处理完成后退出该子进程,fork-and-execute。
2.CGI方式是客户端有多少个请求,就开辟多少个子进程,每个子进程都需要启动自己的解释器,加载配置,链接其他服务器等初始化工作,这种工作模式导致CGI性能低下。
3.CGI使外部程序与Web服务器之间交互成为可能。CGI程序运行在独立的进程中,并对每个web请求建立一个进程,当面对大量请求时,进程的大量建立和消亡使得OS的性能严重下降,并且因为地址空间无法共享,也限制了资源重用。
FastCGI
快速通用网关接口(Fast Common Gateway Interface/FastCGI)是通用网关接口的改进,描述了客户端和服务器程序之间传输数据的一种标准。FastCGI使用持续的进程来处理一连串的请求,这些请求由FastCGI进程管理器进行管理,而不是web服务器。
FastCGI处理流程图如下:
1.web服务器启动加载FastCGI执行环境。
2.FastCGI进程管理器自身初始化,启动多个CGI解释器进程并等待来自web服务器的链接,启动FastCGI进程时,可以配置以ip和UNIX域socket两种方式启动。
3.当客户端请求到达web服务器时,web服务器将请求采用socket方式转发到FastCGI主进程,Fast主进程选择并连接到一个CGI解释器,web服务器将CGI环境变量和标准输入发送到FastCGI子进程。
4.FastCGI子进程完成处理将标准输出和错误信息从同一socket链接返回web服务器,当FastCGI子进程关闭连接时,请求处理完成。
5.等待下一个链接
FastCGI像是一个常驻型CGI,可以一直执行,不是fork-and-execute模式
2.进程管理器:spawn-fcgi
Nginx不能像Apache那样直接执行外部可执行程序,但是Nginx可以作为代理Server,将请求转发给后端服务器,支持FastCGI代理,接受客户端的请求,然后将请求转发给后端的FastCGI进程。
spawn-fcgi使用pre-fork模型,主要功能是打开监听端口,绑定地址,然后fork-and-exec创建FastCGI应用程序进程,退出完成工作。FastCGI应用程序初始化,然后进入死循环侦听socket的链接请求。
参数 | 含义 |
---|---|
f | 指定调用FastCGI进程的执行程序的位置 |
-a | 绑定到地址addr |
-p | 绑定到端口port |
-s | 绑定到unix domain socket |
-C | 指定产生的FastCGI的进程数,默认为5(用于PHP) |
-P | 指定产生的进程的PID文件路径 |
-F | 指定产生FastCGI的进程数(C) |
-u和-g FastCGI | 使用什么身份运行 |
3.fcgi测试程序
编写一个反射服务器程序
#include "fcgi_config.h"
#include <stdlib.h>
#include <unistd.h>
#include "fcgi_stdio.h"
static void printEnv(char *label,char **envp)
{
printf("%s:<br>\n<pre>\n",label);
for(;*envp != NULL;envp++){
printf("%s\n",*envp);
}
printf("</pre><p>");
}
int main()
{
char **initialEnv = environ;
int count = 0;
while(FCGI_Accept()>=0){
char *contentLength = getenv("CONTENT_LENGTH");
int len;
}
printf("Content-type: text/html\r\n"
"\r\n"
"<title>FastCGI echo</title>"
"<h1>FastCGI echo</h1>\n"
"Request number %d, Process ID: %d<p>\n", ++count, getpid());
if(contentLength != NULL){
len = strtol(contentLength,NULL,10);
}else{
len = 0;
}
if(len <= 0){
printf("No data from standard input.<p>\n");
}else{
int i,ch;
printf("Standard input:<br>\n<pre>\n");
for (i = 0; i < len; i++) {
if ((ch = getchar()) < 0) { printf("Error: Not enough bytes received on standard input<p>\n");
break;
}
putchar(ch);
}
printf("\n</pre><p>\n");
}
printEnv("Request environment",environ);
printEnv("Initial environment",initialEnv);
}
return 0;
}
开启spawn-fcgi进程管理器
spawn-fcgi -a 127.0.0.1 -p 8001 -f ./echo
开启成功
nginx.conf配置文件编写如下
server{
listen 80;
server_name localhost;
location / {
root zyFile2;
index demo.html;
}
location /test {
fastcgi_pass 127.0.0.1:8001 #这里的IP与spawn-fcgi开启指令相同
include fastcgi.conf;
}
}
访问页面效果如下
FastCGI配置完成