FastCGI的工作原理
1、Web Server启动时载入FastCGI进程管理器(IIS ISAPI或Apache Module)
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通常有多慢。每一个Web请求PHP都必须重新解析php.ini、重新载入全部扩展并重初始化全部数据结构。使用FastCGI,所有这些都只在进程启动时发生一次。一个额外的好处是,持续数据库连接(Persistent database connection)可以工作。
这个很容易找到。也容易理解,但是继续google之后,发现自己的概念又模糊了。
比如有些例子用
spawn-fcgi
/usr/local/bin/spawn-fcgi -a 127.0.0.1 -p 9000 -C 5 -u root -g root -f /usr/bin/php-cgi
参数含义如下
- -f <fcgiapp> 指定调用FastCGI的进程的执行程序位置,根据系统上所装的PHP的情况具体设置
- -a <addr> 绑定到地址addr
- -p <port> 绑定到端口port
- -s <path> 绑定到unix socket的路径path
- -C <childs> 指定产生的FastCGI的进程数,默认为5(仅用于PHP)
- -P <path> 指定产生的进程的PID文件路径
- -u和-g FastCGI使用什么身份(-u 用户 -g 用户组)运行,Ubuntu下可以使用www-data,其他的根据情况配置,如nobody、apache等
刚看到FastCGI原理的时候,我想象中的运行模型是,前端的反向代理服务器如Nginx收到请求,然后转发给cgi进程,这个cgi进程有N个,从而实现并发处理。但是接下来搜索到的C语言实现的FastCGI应用的例子好像又把这个模型给否定了。并且fastcgi是语言无关的,难道你要用python写并发?
#include "fcgi_stdio.h"
#include <stdlib.h>
int count;
void initialize(void)
{
count=0;
}
void main(void)
{
initialize();
while (FCGI_Accept() >= 0) {
printf("Content-type: text/html“r“n"
"“r“n"
"<title>FastCGI Hello! (C, fcgi_stdio library)</title>"
"<h1>FastCGI Hello! (C, fcgi_stdio library)</h1>"
"Request number %d running on host <i>%s</i>“n",
++count, getenv("SERVER_HOSTNAME"));
}
}
这个代码看不出来有任何并发处理的部分。比如fork什么的。
另外一种模型就是有一种叫做FastCGI进程管理器的进程,就像上面说的是管理fastcgi进程的进程,请求转发到管理器的时候,由它来进行选择相应的应用进程,卡就卡在这了,这个管理器是怎么来选择进程的啊,假如我有N个不同逻辑的可执行文件,它怎么知道要转发给哪个进程呢,google到的fastcgi配置都是针对反向代理的后端也即管理器设置的,没有发现有针对不同逻辑发给不同的应用进程的部分。
继续狂搜,还是无果,都是类似的文章。网上搜索不到的问题,要么就是很难很偏,要么就是很简单,简单到不值一提,很显然,我属于后者。转换思路,开始考虑假如要自己来实现这个功能的话该怎么办。一步步地推理,在结合搜索到的文章,大概理清了思路,我的理解如下,不对的地方请指正。
1.有一个CGI进程管理器,这个管理器一般是用第3方的fastcgi开发套件,比如上面提到的spawn-fcgi ,用它可以启动指定可执行文件的N个实例,关于之前选择进程的疑问,这里可以得到解释,那就是多个进程只是同一个可执行文件的实例,假如你想把不同的模块分开生成可执行文件的话估计就得再启动多一个管理器了吧。
2.假如你是用python写的fastcgi的应用程序,那么当你用管理器启动了100个实例的时候,也就相当于启动了100个python解析器,如果是用C等静态语言写的话那还好,只是跟你写的程序大小有关。
可能是没有接触过CGI程序的原因,让我对这基本的模型都纠结了一下午,希望这篇文章能帮些初学者。