最好的理解莫过于demo实例
参考http://docs.oracle.com/cd/E19146-01/820-0872/auto136/index.html
http://www.fastcgi.com/devkit/doc/fcgi-devel-kit.htm#S3
fastcgi 下载地址:http://www.fastcgi.com/drupal/node/5
安装
tar zxvf fcgi.tar.gz
mkdir fcgi-build
cd fcgi-build
../fcgi-2.4.1-SNAP-0311112127/configure
make
此时不出意外会出现如下错误
../../fcgi-2.4.1-SNAP-0311112127/libfcgi/fcgio.cpp: In member function 'virtual int fcgi_streambuf::underflow()':
../../fcgi-2.4.1-SNAP-0311112127/libfcgi/fcgio.cpp:113:35: error: 'EOF' was not declared in this scope
if (glen <= 0) return EOF;
^
Makefile:311: recipe for target 'fcgio.lo' failed
make[2]: *** [fcgio.lo] Error 1
make[2]: Leaving directory '/root/fcgi-tool/fcgi-build/libfcgi'
Makefile:279: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/root/fcgi-tool/fcgi-build'
Makefile:201: recipe for target 'all' failed
make: *** [all] Error 2
解决方案是
vi fcgi-2.4.1-SNAP-0311112127/libfcgi/fcgio.cpp
加入头文件#include "stdio.h"
问题解决,重新编译
cd fcgi-build
make clean
../fcgi-2.4.1-SNAP-0311112127/configure
make
makse install
默认安装在/usr/local/include 和 /usr/local/lib
安装就到此为止了
接下来就试一试吧!
文件tiny-fcgi.c内容如下:
#include "fcgi_stdio.h"
#include <stdlib.h>
void main(void)
{
int count = 0;
while(FCGI_Accept() >= 0)
printf("Content-type: text/html\r\n"
"\r\n"
"<title>FastCGI Hello!</title>"
"<h1>FastCGI Hello!</h1>"
"Request number %d running on host <i>%s</i>\n",
++count, getenv("SERVER_NAME"));
}
直接编译
gcc -o tiny-fcgi.cgi tiny-cgi -lfcgi
fcgi是第三方库, -lfcgi表示编译时需要使用libfcgi这个库。
会报undefined reference to FCGI_printf
该觉十分纳闷,为此笔者还去网上查询了gcc编译时的搜索路径
地址为:http://www.cnblogs.com/zhengmeifu/archive/2010/03/02/linux-gcc_compile_header_file_and_lib_path.html
这篇博文中提到,gcc会搜索/usr/local/lib这个文件夹,经过试验发现并没有搜索到
看来只有把libfcgi显示的写出来,这样试一试
gcc -L/usr/local/libfcgi.so -lfcgi -o tiny-fcgi.cgi tiny-fcgi.c
这样就编译通过了
./tiny-fcgi.cgi 会报XXXX.so.0找不到的错误
看来只有把/usr/local/lib下的libfcgi*的所有文件拷贝到/usr/lib文件夹下,因为gcc编译时 -lfcgi 只会去/usr/lib目录下搜索,这样就不用显示的写libfcgi.so
而且执行成功了
输出:
Content-type: text/html
<title>FastCGI Hello!</title><h1>FastCGI Hello!</h1>Request number 1 running on host <i>(null)</i>
接着往下走
根据官方文档指出,使用cgi-fcgi 可以与任何支持fastcgi的web服务器通信
直接在终端中输入cgi-fcgi
会出现如下内容:
Usage:
cgi-fcgi -f <cmdPath> , or
cgi-fcgi -connect <connName> <appPath> [<nServers>] , or
cgi-fcgi -start -connect <connName> <appPath> [<nServers>] , or
cgi-fcgi -bind -connect <connName> ,
where <connName> is either the pathname of a UNIX domain socket
or (if -bind is given) a hostName:portNumber specification
or (if -start is given) a :portNumber specification (uses local host).
这里提到了很重要的一点是
fastcgi 与 web服务器的通讯方式有两种:
一种是通过tcp/ip协议
另一种是通过UNIX domain socket
这两种方式各有优缺点
tcp/ip协议支持分布式部署,也就是web 核心服务程序和cgi服务程序分开部署,通过tcp/ip协议进行连接,不过相对于UNIX domain socket速度慢,不过可靠性要好一些,毕竟是面向连接的
UNIX domain socket只能将web核心服务程序和cgi服务程序部署在同一台服务器,虽然速度快,但是系统稳定性相对较差
首先来看看tcp/ip协议下web服务器与cgi服务的通讯方式
使用nginx服务器
打开nginx配置文件
vi nginx.conf
找到server分节:
配置如下
location ~ \.fcgi$ {
root html;
fastcgi_pass 127.0.0.1:9006;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_n
ame;
include fastcgi_params;
}
接着运行命令
cgi-fcgi -start -connect :9006 tiny-fcgi.cgi(默认启用localhost)
或者cgi-fcgi -start -connect 127.0.0.1:9006 tiny-fcgi.cgi
通过http://192.168.172.128/tiny-fcgi.cgi 就能访问
接着说说UNXI domain socket 的访问方式
首先建立UNIX domain socket 文件,并将该文件权限设置为666,授权给nginx用户
同时需要保证启动cgi服务的时候也是在nginx用户下启动,否则无法通信
命令如下:
touch /dev/shm/tiny-fcgi.sock
groupadd nginx
useradd -g nginx nginx
chown nginx:nginx tiny-fcgi.sock
chmod 666 tiny-fcgi.sock
打开nginx.conf文件找到server分节做如下设置:
location ~ \.fcgi$ {
root html;
fastcgi_pass unix:/dev/shm/tiny-fcgi.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_
name;
include fastcgi_params;
}
启动cgi服务时一定要在nginx用户下,命令如下:
cgi-fcgi -start -connect /dev/shm/tiny-fcgi.sock /mnt/hgfs/share/workspace/c-workspace/tiny-fcgi.cgi
通过http://192.168.172.128/tiny-fcgi.cgi 就能访问
至于如何选择web服务器与cgi服务之间的通讯方式,网上有不少解答。
笔者目前还很菜,有不对的地方请大家批评指正。