http://huichen.org/2010/03/12/configure-fastcgi-for-nginx/
這是一篇講述怎樣在Nginx下配置fastcgi的文章。
適用
Nginx通過fastcgi調(diào)用python, Perl和C++等寫的CGI程序。PHP有PHP-FPM (FastCGI Process Manager),這個(gè)對(duì)PHP來說更好的FastCGI進(jìn)程管理器,關(guān)于PHP-FPM的更多信息,請(qǐng)Google php-fpm+nginx。
原理
Nginx并不提供支持對(duì)外部程序的直接調(diào)用或者解析(所以缺少像apache里的mod_php這樣的模塊),所有的外部程序(包括PHP)必須通過fastcgi接口來調(diào)用,在Linux下接口是socket (文件socket或者Internet socket)。所以為了調(diào)用CGI程序,我們需要一個(gè)fastcgi的wrapper,這個(gè)wrapper綁定在某個(gè)固定socket上(比如端口或者文件socket),當(dāng)nginx將CGI請(qǐng)求發(fā)送給這個(gè)socket的時(shí)候,wrapper接納請(qǐng)求并fork一個(gè)新的線程,這個(gè)線程調(diào)用外部的程序或者解釋器處理腳本并讀取返回值,而wrapper再將返回的數(shù)據(jù)(網(wǎng)頁(yè)或者圖片等)通過fastcgi將數(shù)據(jù)通過那個(gè)固定的socket傳遞給nginx。示意圖如下:

Ningx的FastCGI原理
所以,我們首先需要一個(gè)wrapper,這個(gè)wrapper需要完成的工作:
1. 通過調(diào)用fastcgi(庫(kù))的函數(shù)通過socket和ningx通信(讀寫socket是fastcgi內(nèi)部實(shí)現(xiàn)的功能,對(duì)wrapper是非透明的)
2. 調(diào)度thread,進(jìn)行fork和kill
3. 和application進(jìn)行通信
Wrapper的實(shí)現(xiàn)
在Nginx的官方wiki中給出了一個(gè)Perl寫的wrapper例子,顯然這需要安裝Perl和必要的module(比如FCGI)。為了追求效率,我們希望有一個(gè)C寫的wrapper。我找到了這個(gè)fcgiwrap項(xiàng)目。
只有wrapper還是不夠的,我們需要一個(gè)腳本來建立socket,啟動(dòng)wrapper以及將wrapper和socket綁定。你可以從我的服務(wù)器上下載這個(gè)C的wrapper和啟動(dòng)腳本。啟動(dòng)腳本spawn-fcgi的內(nèi)容如下:
幫助
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執(zhí)行文件,domain socket的位置和同時(shí)運(yùn)行的fcgiwrap進(jìn)程的個(gè)數(shù)。后兩個(gè)參數(shù)也可以通過調(diào)用spawn-fcgi的命令行傳遞。
建議你用www-data或者nginx等低權(quán)限帳號(hào)而不是root來運(yùn)行這個(gè)spawn-fcgi腳本,這要求該帳號(hào)能夠讀寫那個(gè)socket文件所在的文件夾(上面的例子中是 /var/run/nginx/ )。
如果你的機(jī)器沒有Perl,你可以下載編譯一個(gè)C寫的spawn-fcgi (本地備份),這是lighttpd中的一個(gè)子項(xiàng)目,調(diào)用這個(gè)C版本的spawn-fcgi時(shí)可以通過命令行指定domain socket等信息。
Nginx配置
相應(yīng)地,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會(huì)報(bào)錯(cuò)。
此條目發(fā)表在 互聯(lián)網(wǎng) 分類目錄,貼了 cgi, domain socket, fastcgi, lighttpd, nginx, php, php-fpm, wrapper 標(biāo)簽。將固定鏈接加入收藏夾。
← PhotonVPS 測(cè)評(píng)
trAlyzr: 一個(gè)測(cè)試網(wǎng)站響應(yīng)速度的工具包 →
《Nginx下配置FastCGI》有 1 條評(píng)論
1.
dengx 說:
四月 23, 20109:31 下午
看了這個(gè)個(gè)圖,思路清晰了很多,以前對(duì)fastcgi和wrapper之間的關(guān)系很模糊。