Perl(FastCGI)的安装

PerlFastCGI的安装
1.获取wrapper程序

读者可以从http://www.nginx.eu/nginx-fcgi/ 上下载nginx-fcgi.txt文件然后将其命名为nginx-fcgi.pl并放到/usr/local/nginx目录下。nginx-fcgi.pl是一个用Perl脚本写的wrapper实例所以操作系统必须要安装Perl程序以及相关模块。

2.安装相关的系统支持模块

可以从http://search.cpan.org下载所需的相应模块然后进行安装。
1安装FCGI模块
[root@localhost opt]# tar zxvf FCGI-0.71.tar.gz  
[root@localhost opt]# cd FCGI-0.71  
[root@localhost FCGI-0.71]# perl Makefile.PL  
[root@localhost FCGI-0.71]# make  
[root@localhost FCGI-0.71]# make install
2安装IO模块
root@localhost opt]# tar -xvzf IO-1.25.tar.gz  
[root@localhost opt]# cd IO-1.25  
[root@localhost IO-1.25]# perl Makefile.PL  
[root@localhost IO-1.25]# make  
[root@localhost IO-1.25]# make install
3安装IO-ALL模块
[root@localhost opt]# tar -xvzf IO-All-0.39.tar.gz  
[root@localhost opt]# cd IO-ALL-0.39  
[root@localhost IO-ALL-0.39]# perl Makefile.PL  
[root@localhost IO-ALL-0.39]#make  
[root@localhost IO-ALL-0.39]#make install
3.编写nginx-fcgi启动脚本
仅仅有wrapper文件是不够的还需要一个脚本来创建socket、启动wrapper以及将wrapper和socket绑定。下面通过一个shell脚本来完成这一系列工作。
[root@localhost root]# more nginx-fcgi
#!/bin/bash  
nginxroot=/usr/local/nginx  
start ()  
{  
chown www.www $nginxroot/logs  
echo "$nginxroot/nginx-fcgi.pl -l $nginxroot/logs/nginx-fcgi.log -pid $nginxroot/logs/nginx-fcgi.pid  -S  $nginxroot/logs/nginx-fcgi.sock" >>$nginxroot/nginx_fcgi.sh  
chown www.www  $nginxroot/nginx_fcgi.sh  
chmod 755 $nginxroot/nginx_fcgi.sh  
sudo -u www $nginxroot/nginx_fcgi.sh  
echo "start nginx-fcgi done"  
}  
stop ()  
{  
kill $(cat $nginxroot/logs/nginx-fcgi.pid)  
rm $nginxroot/logs/nginx-fcgi.pid 2>/dev/null  
rm $nginxroot/logs/nginx-fcgi.sock 2>/dev/null  
rm $nginxroot/nginx_fcgi.sh 2>/dev/null  
echo "stop nginx-fcgi done"  
}  
case $1 in  
stop)  
stop  
;;  
start)  
start  
;;  
restart)  
stop  
start  
;;  
*)  
echo $"Usage: perl-cgi {start|stop|restart}"  
      exit 1  
esac
在nginx-fcgi中变量nginxroot用于指定Nginx的安装目录nginx-fcgi.sock是生成的文件sockwww为运行nginx_fcgi进程的用户这个用户要和运行Nginx的用户一致
注意如果在安装nginx的时候指定运行的用户为www上面的脚本里面的进程用户也应该是www否则访问提示权限不足。
配置完脚本后将此文件放到/usr/local/nginx目录下接着通过如下方式管理nginx-fcgi进程
[root@localhost root]#chmod 755 /usr/local/nginx/nginx-fcgi.pl
[root@localhost root]#cat nginx-fcgi.pl
#!/usr/bin/perl
#
#authorDaniel Dominik Rudnicki
#thanks to:Piotr Romanczuk
#version0.4.3
#webpagehttp://www.nginx.eu/
#
#BASED @ http://wiki.codemongers.com/NginxSimpleCGI
#
#
# use strict;
use FCGI;
use Getopt::Long;
use IO::All;
use Socket;

sub init {
GetOptions("h"=> \$help,
"verbose!"=>\$verbose,
"pid=s"=> \$filepid,
"l=s" => \$logfile,
"S:s"   => \$unixsocket,
"P:i"   => \$unixport) or usage();
usage() if $help;

print "Starting Nginx-fcgi\n" if $verbose;
print "Running with $> UID" if $verbose;
print "Perl $]" if $verbose;

#if ( $> == "0" ) {
#print "\n\tERROR\tRunning as a root!\n";
#print "\tSuggested not to do so !!!\n\n";
#exit 1;
#}

       if ( ! $logfile ) {
print "\n\tERROR\t log file must declared\n"
. "\tuse $0 with option -l filename\n\n";
exit 1;
}
print "Using log file $logfile\n" if $verbose;
"\n\n" >> io($logfile);
addlog($logfile, "Starting Nginx-cfgi");
addlog($logfile, "Running with $> UID");
addlog($logfile, "Perl $]");
addlog($logfile, "Testing socket options");

if ( ($unixsocket && $unixport) || (!($unixsocket) && !($unixport)) ) {
print "\n\tERROR\tOnly one option can be used!\n";
print "\tSuggested (beacuse of speed) is usage UNIX socket -S \n\n";
exit 1;
}

if ($unixsocket) {
print "Daemon listening at UNIX socket $unixsocket\n" if $versbose;
addlog($logfile, "Deamon listening at UNIX socket $unixsocket");
} else {
print "Daemon listening at TCP/IP socket *:$unixport\n" if $verbose;
#
addlog($logfile, "Daemon listening at TCP/IP socket *:$unixport");
}

if ( -e $filepid ) {
print "\n\tERROR\t PID file $filepid already exists\n\n";
addlog($logfile, "Can not use PID file $filepid, already exists.");
exit 1;
}

if ( $unixsocket ) {
print "Creating UNIX socket\n" if $verbose;
$socket = FCGI::OpenSocket( $unixsocket, 10 );
if ( !$socket) {
print "Couldn't create socket\n";
addlog($logfile, "Couldn't create socket");
exit 1;
}
print "Using UNIX socket $unixsocket\n" if $verbose;
} else {
print "Creating TCP/IP socket\n" if $verbose;
$portnumber = ":".$unixport;
$socket = FCGI::OpenSocket( $unixport, 10 );
if ( !$socket ) {
print "Couldn't create socket\n";
addlog($logfile, "Couldn't create socket");
exit 1;
}
print " Using port $unixport\n" if $verbose;
}
addlog($logfile, "Socket created");

if ( ! $filepid ) {
print "\n\tERROR\t PID file must declared\n"
. "\tuse $0 with option -pid filename\n\n";
exit 1;
}
print "Using PID file $filepid\n" if $verbose;
addlog($logfile, "Using PID file $filepid");

my $pidnumber = $$;
$pidnumber > io($filepid);
print " PID number $$\n" if $verbose;
addlog($logfile, "PID number $pidnumber");
}

sub addzero {
my ($date) = shift;
if ($date < 10) {
return "0$date";
}
      return $date;
}

sub logformat {
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$iddst) = localtime(time);
my $datestring;
$year += 1900;
$mon++;
$mon  = addzero($mon);
$mday = addzero($mday);
$min  = addzero($min);
$datestring = "$year-$mon-$mday $hour:$min";
return($datestring);
}

sub addlog {
my ($log_file, $log_message) = @_;
my $curr_time = logformat();
my $write_message = "[$curr_time]   $log_message";
$write_message >> io($log_file);
"\n" >> io($log_file);
}

sub printerror {
my $message = @_;
print "\nNginx FastCGI\tERROR\n"
. "\t $message\n\n";
exit 1;
}

sub usage {
print "\nNginx FastCGI \n"
. "\n\tusage: $0 [-h] -S string -P int\n"
. "\n\t-h\t\t: this (help) message"
. "\n\t-S path\t\t: path for UNIX socket"
. "\n\t-P port\t\t: port number"
. "\n\t-p file\t\t: path for pid file"
. "\n\t-l file\t\t: path for logfile"
. "\n\n\texample: $0 -S /var/run/nginx-perl_cgi.sock -l /var/log/nginx/nginx-cfgi.log -pid /var/run/nginx-fcgi.pid\n\n";
exit 1;
}


init;
#
END() { } BEGIN() { }
*CORE::GLOBAL::exit = sub { die "fakeexit\nrc=".shift()."\n"; }; eval q{exit};
if ($@) {
exit unless $@ =~ /^fakeexit/;
} ;

# fork part
my $pid = fork();

if( $pid == 0 ) {
&main;
exit 0;
}

print " Forking worker process with PID $pid\n" if $verbose;
addlog($logfile, "Forking worker process with PID $pid");
print " Update PID file $filepid\n" if $verbose;
addlog($logfile, "Update PID file $filepid");
$pid > io($filepid);
print "Worker process running.\n" if $verbose;
addlog ($logfile, "Parent process $$ is exiting");
exit 0;

sub main {
$request = FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%req_params, $socket );
if ($request) { request_loop()};
FCGI::CloseSocket( $socket );
}

sub request_loop {
while( $request->Accept() >= 0 ) {
# processing any STDIN input from WebServer (for CGI-POST actions)
$stdin_passthrough = '';
$req_len = 0 + $req_params{'CONTENT_LENGTH'};
if (($req_params{'REQUEST_METHOD'} eq 'POST') && ($req_len != 0) ){
while ($req_len) {
$stdin_passthrough .= getc(STDIN);
$req_len--;
}
}

# running the cgi app
if ( (-x $req_params{SCRIPT_FILENAME}) &&
(-s $req_params{SCRIPT_FILENAME}) &&
(-r $req_params{SCRIPT_FILENAME})
){
foreach $key ( keys %req_params){
$ENV{$key} = $req_params{$key};
}
if ( $verbose ) {
addlog($logfile, "running $req_params{SCRIPT_FILENAME}");
}
# http://perldoc.perl.org/perlipc.html#Safe-Pipe-Opens
#
open $cgi_app, '-|', $req_params{SCRIPT_FILENAME}, $stdin_passthrough or print("Content-type: text/plain\r\n\r\n"); print "Error: CGI app returned no output - Executing $req_params{SCRIPT_FILENAME} failed !\n"; # addlog($logfile, "Error: CGI app returned no output - Executing $req_params{SCRIPT_FILENAME} failed !");
if ($cgi_app) {
print <$cgi_app>;
close $cgi_app;
}
} else {
print("Content-type: text/plain\r\n\r\n");
print "Error: No such CGI app - $req_params{SCRIPT_FILENAME} may not exist or is not executable by this process.\n";
addlog($logfile, "Error: No such CGI app - $req_params{SCRIPT_FILENAME} may not exist or is not executable by this process.");
}
}
}
上面的文件可以从goole上下载。

[root@localhost root]#chmod 755 /usr/local/nginx/nginx-fcgi
[root@localhost root]#/usr/local/nginx/nginx-fcgi start|stop|restart
1.8.2 为Nginx添加FCGI支持
修改Nginx配置文件在server虚拟主机中添加如下配置

location ~ \.cgi$ {  
     root            html;  
     fastcgi_pass    unix:/usr/local/nginx/logs/nginx-fcgi.sock;  
     fastcgi_index   index.cgi;  
     fastcgi_param   SCRIPT_FILENAME  $document_root$fastcgi_script_name;  
     include         fastcgi_params;  
}

在这个location配置中Nginx与FastCGI的通信方式为Unix Socket。根据经验IP Socket在高并发访问下比Unix Socket稳定但Unix Socket速度要比IP Socket快。 “$document_root”是虚拟主机的根目录在这里是/usr/local/nginx/html目录。
1.8.3 测试Nginx +Perl(FastCGI)

所有配置工作完成后即可启动服务了。首先启动nginx-fcgi进程操作如下

/usr/local/nginx/nginx-fcgi start
然后启动nginx服务。
/usr/local/nginx/sbin/nginx
下面在/usr/local/nginx/html目录下创建一个test.cgi的文件。
# disable filename globbing  
set -f  
echo "Content-type: text/plain; charset=iso-8859-1"  
echo  
echo CGI/1.0 test script report:  
echo  
echo argc is $#. argv is "$*".  
echo  
echo SERVER_SOFTWARE = $SERVER_SOFTWARE  
echo SERVER_NAME = $SERVER_NAME  
echo GATEWAY_INTERFACE = $GATEWAY_INTERFACE  
echo SERVER_PROTOCOL = $SERVER_PROTOCOL  
echo SERVER_PORT = $SERVER_PORT  
echo REQUEST_METHOD = $REQUEST_METHOD  
echo REMOTE_ADDR = $REMOTE_ADDR
接着通过浏览器访问test.cgi文件如果显示与下面类似的信息表明Nginx+Perl环境搭建成功。

101203312.png

你可能感兴趣的:(操作系统,local,程序,命名,读者)