http://huichen.org/2010/03/12/configure-fastcgi-for-nginx/
这是一篇讲述怎样在Nginx下配置fastcgi的文章。
适用
Nginx通过fastcgi调用python, Perl和C++等写的CGI程序。PHP有PHP-FPM (FastCGI Process Manager),这个对PHP来说更好的FastCGI进程管理器,关于PHP-FPM的更多信息,请Google php-fpm+nginx。
原理
Nginx并不提供支持对外部程序的直接调用或者解析(所以缺少像apache里的mod_php这样的模块),所有的外部程序(包括PHP)必须通过fastcgi接口来调用,在Linux下接口是socket (文件socket或者Internet socket)。所以为了调用CGI程序,我们需要一个fastcgi的wrapper,这个wrapper绑定在某个固定socket上(比如端口或者文件socket),当nginx将CGI请求发送给这个socket的时候,wrapper接纳请求并fork一个新的线程,这个线程调用外部的程序或者解释器处理脚本并读取返回值,而wrapper再将返回的数据(网页或者图片等)通过fastcgi将数据通过那个固定的socket传递给nginx。示意图如下:
Ningx的FastCGI原理
所以,我们首先需要一个wrapper,这个wrapper需要完成的工作:
1. 通过调用fastcgi(库)的函数通过socket和ningx通信(读写socket是fastcgi内部实现的功能,对wrapper是非透明的)
2. 调度thread,进行fork和kill
3. 和application进行通信
Wrapper的实现
在Nginx的官方wiki中给出了一个Perl写的wrapper例子,显然这需要安装Perl和必要的module(比如FCGI)。为了追求效率,我们希望有一个C写的wrapper。我找到了这个fcgiwrap项目。
只有wrapper还是不够的,我们需要一个脚本来建立socket,启动wrapper以及将wrapper和socket绑定。你可以从我的服务器上下载这个C的wrapper和启动脚本。启动脚本spawn-fcgi的内容如下:
帮助
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #!/usr/bin/perl use strict; use warnings FATAL => qw( all ); use IO::Socket::UNIX; my $bin_path = '/usr/sbin/fcgiwrap'; my $socket_path = $ARGV[0] || '/var/run/nginx/nginx-fcgi.sock'; my $num_children = $ARGV[1] || 4; close STDIN; unlink $socket_path; my $socket = IO::Socket::UNIX->new( Local => $socket_path, Listen => 100, ); die "Cannot create socket at $socket_path: $!\n" unless $socket; for (1 .. $num_children) { my $pid = fork; die "Cannot fork: $!" unless defined $pid; next if $pid; exec $bin_path; die "Failed to exec $bin_path: $!\n"; } |
你需要修改脚本中高亮的三行,分别是你编译后的fcgiwrap执行文件,domain socket的位置和同时运行的fcgiwrap进程的个数。后两个参数也可以通过调用spawn-fcgi的命令行传递。
建议你用www-data或者nginx等低权限帐号而不是root来运行这个spawn-fcgi脚本,这要求该帐号能够读写那个socket文件所在的文件夹(上面的例子中是 /var/run/nginx/ )。
如果你的机器没有Perl,你可以下载编译一个C写的spawn-fcgi (本地备份),这是lighttpd中的一个子项目,调用这个C版本的spawn-fcgi时可以通过命令行指定domain socket等信息。
Nginx配置
相应地,nginx中需要做如下配置。在你的site文件的server{…}中加入:
帮助
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | location ~ ^.+\.cgi$ { root /var/www/yoursite.com; gzip off; #gzip makes scripts feel slower since they have to complete before getting gzipped fastcgi_pass unix:/var/run/nginx/nginx-fcgi.sock; fastcgi_read_timeout 5m; fastcgi_param SCRIPT_FILENAME /var/www/yoursite$fastcgi_script_name; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE Nginx; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; } |
你需要把上面高亮的三行修改为你的配置。注意root一行是必须的,否则wrapper会报错。
此条目发表在 互联网 分类目录,贴了 cgi, domain socket, fastcgi, lighttpd, nginx, php, php-fpm, wrapper 标签。将固定链接加入收藏夹。
← PhotonVPS 测评
trAlyzr: 一个测试网站响应速度的工具包 →
《Nginx下配置FastCGI》有 1 条评论
1. dengx 说:
四月 23, 20109:31 下午
看了这个个图,思路清晰了很多,以前对fastcgi和wrapper之间的关系很模糊。