perl + fastcgi + nginx搭建
nginx +?fastcgi是php下最流行的一套环境了,那perl会不会也有fastcgi呢,当然有,今天来搭建下nginx下perl的fastcgi. 性能方面也不亚于php,但是现在web程序php的流行程度perl无法比拟了,性能再好也枉然,但是部分小功能可以考虑使用perl的fastcgi 来搞定.进入正题. 1. 准备软件环境: nginx:http://www.nginx.org 1.1 nginx安装 1.2 perl安装 # yum install perl 1.3 perl-fastcgi安装 # cd /usr/local/src # wget http://www.cpan.org/modules/by-module/FCGI/FCGI-0.74.tar.gz # tar -xzvf FCGI-0.74.tar.gz # cd FCGI-0.74 # perl Makefile.PL # make # make install 2. nginx虚拟主机配置server { ??????? listen?????? 81; ??????? server_name? test.ttlsa.com; ??????? #access_log? /data/logs/nginx/test.ttlsa.com.access.log? main; ??????? index index.html index.php index.html; ??????? root /data/site/test.ttlsa.com; ??????? location / ?? ??? ?{ ?? ??? ?} ?? ??? ?location ~ .pl$ ?? ??? ?{ ?? ??? ??? ?include fastcgi_params; ?? ??? ??? ?fastcgi_pass? 127.0.0.1:8999; ?? ??? ??? ?#fastcgi_pass? unix:/var/run/ttlsa.com.perl.sock; ?? ??? ??? ?fastcgi_index index.pl; ?? ??? ?} } 如果想把tcp/ip方式改为socket方式,可以修改fastcgi-wrapper.pl. $socket = FCGI::OpenSocket( "127.0.0.1:8999",10 ); #use IP sockets 改为 $socket = FCGI::OpenSocket( "/var/run/ttlsa.com.perl.sock",10 ); #use IP sockets 3. 配置脚本 3.1 fastcgi监听脚本 #!/usr/bin/perl use FCGI; use Socket; use POSIX qw(setsid); require 'syscall.ph'; &daemonize; #this keeps the program alive or something after exec'ing perl scripts END() { } BEGIN() { } *CORE::GLOBAL::exit = sub { die "fakeexitnrc=".shift()."n"; }; eval q{exit}; if ($@) { ??? exit unless $@ =~ /^fakeexit/; }; &main; sub daemonize() { ??? chdir '/'???????????????? or die "Can't chdir to /: $!"; ??? defined(my $pid = fork)?? or die "Can't fork: $!"; ??? exit if $pid; ??? setsid??????????????????? or die "Can't start a new session: $!"; ??? umask 0; } sub main { ??????? $socket = FCGI::OpenSocket( "127.0.0.1:8999",10 ); #use IP sockets ??????? $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) ){ ??????????????? my $bytes_read = 0; ??????????????? while ($bytes_read < $req_len) { ??????????????????????? my $data = ''; ??????????????????????? my $bytes = read(STDIN,$data,($req_len - $bytes_read)); ??????????????????????? last if ($bytes == 0 || !defined($bytes)); ??????????????????????? $stdin_passthrough .= $data; ??????????????????????? $bytes_read += $bytes; ??????????????? } ??????????? } ??????????? #running the cgi app ??????????? if ( (-x $req_params{SCRIPT_FILENAME}) &&? #can I execute this? ???????????????? (-s $req_params{SCRIPT_FILENAME}) &&? #Is this file empty? ???????????????? (-r $req_params{SCRIPT_FILENAME})???? #can I read this file? ??????????? ){ ??????? pipe(CHILD_RD,PARENT_WR); ??????? my $pid = open(KID_TO_READ,"-|"); ??????? unless(defined($pid)) { ??????????? print("Content-type: text/plainrnrn"); ??????????????????????? print "Error: CGI app returned no output - "; ??????????????????????? print "Executing $req_params{SCRIPT_FILENAME} failed !n"; ??????????? next; ??????? } ??????? if ($pid > 0) { ??????????? close(CHILD_RD); ??????????? print PARENT_WR $stdin_passthrough; ??????????? close(PARENT_WR); ??????????? while(my $s = <KID_TO_READ>) { print $s; } ??????????? close KID_TO_READ; ??????????? waitpid($pid,0); ??????? } else { ??????????????????? foreach $key ( keys %req_params){ ?????????????????????? $ENV{$key} = $req_params{$key}; ??????????????????? } ??????????????????? # cd to the script's local directory ??????????????????? if ($req_params{SCRIPT_FILENAME} =~ /^(.*)/[^/]+$/) { ??????????????????????????? chdir $1; ??????????????????? } ??????????? close(PARENT_WR); ??????????? close(STDIN); ??????????? #fcntl(CHILD_RD,F_DUPFD,0); ??????????? syscall(&SYS_dup2,fileno(CHILD_RD),0); ??????????? #open(STDIN,"<&CHILD_RD"); ??????????? exec($req_params{SCRIPT_FILENAME}); ??????????? die("exec failed"); ??????? } ??????????? } ??????????? else { ??????????????? print("Content-type: text/plainrnrn"); ??????????????? print "Error: No such CGI app - $req_params{SCRIPT_FILENAME} may not "; ??????????????? print "exist or is not executable by this process.n"; ??????????? } ??????? } } 3.2 fastcgi自启动服务脚本: 文件路径:/etc/rc.d/init.d/perl-fastcgi #!/bin/sh # # nginx – this script starts and stops the nginx daemon # # chkconfig: - 85 15 # description: Nginx is an HTTP(S) server,HTTP(S) reverse # proxy and IMAP/POP3 proxy server # processname: nginx # config: /opt/nginx/conf/nginx.conf # pidfile: /opt/nginx/logs/nginx.pid # Source function library. . /etc/rc.d/init.d/functions # Source networking configuration. . /etc/sysconfig/network # Check that networking is up. [ "$NETWORKING" = "no" ] && exit 0 perlfastcgi="/usr/bin/fastcgi-wrapper.pl" prog=$(basename perl) lockfile=/var/lock/subsys/perl-fastcgi start() { ??? [ -x $perlfastcgi ] || exit 5 ??? echo -n $"Starting $prog: " ??? daemon $perlfastcgi ??? retval=$? ??? echo ??? [ $retval -eq 0 ] && touch $lockfile ??? return $retval } stop() { ??? echo -n $"Stopping $prog: " ??? killproc $prog -QUIT ??? retval=$? ??? echo ??? [ $retval -eq 0 ] && rm -f $lockfile ??? return $retval } restart() { ??? stop ??? start } reload() { ??? echo -n $”Reloading $prog: ” ??? killproc $nginx -HUP ??? RETVAL=$? ??? echo } force_reload() { ??? restart } rh_status() { ??? status $prog } rh_status_q() { ??? rh_status >/dev/null 2>&1 } case "$1" in ??? start) ??????? rh_status_q && exit 0 ??????? $1 ??????? ;; ??? stop) ??????? rh_status_q || exit 0 ??????? $1 ??????? ;; ??? restart) ??????? $1 ??????? ;; ??? reload) ??????? rh_status_q || exit 7 ??????? $1 ??????? ;; ??? force-reload) ??????? force_reload ??????? ;; ??? status) ??????? rh_status ??????? ;; ??? condrestart|try-restart) ??????? rh_status_q || exit 0 ??????? ;; ??? *) ??????? echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" ??????? exit 2 ??? esac 3.3 设置脚本权限 # chmod a+x /usr/bin/fastcgi-wrapper.pl # chmod a+x /etc/rc.d/init.d/perl-fastcgi 4. FastCGI测试4.1 启动nginx与fastcgi # /usr/local/nginx-1.4.2/sbin/nginx # /etc/init.d/perl-fastcgi start 4.2 perl测试文件: #!/usr/bin/perl print "Content-type:text/htmlnn"; print <<EndOfHTML; <html><head><title>Perl Environment Variables</title></head> <body> <h1>Perl Environment Variables</h1> EndOfHTML foreach $key (sort(keys %ENV)) { ??? print "$key = $ENV{$key}<br>n"; } print "</body></html>"; 5. 访问测试5.1?访问 http://http:test.ttlsa.com/test.pl,出现内容表示OK. ? 6. 简单压力测试: ab -n 1000 -c 10 http://test.ttlsa.com/test.pl 他是在是太慢了,只好用10个并发,共计100个请求来测试.
perl + fastcgi + tcp-ip
6.2 使用socket方式: ab -n 100000 -c 500 http://test.ttlsa.com/test.pl
perl + fastcgi + socket
很奇怪,使用tcp/ip方式,每秒就140多个请求,而使用socket方式却有5800个请求/秒。差距不是一般的大。顺便测试了一下php的fastcgi,大概请求在3000(tcp/ip方式),4800(socket方式)。 7. 文件下载perl脚本下载:perl-fastcgi,fastcgi-wrapper.pl,test.perl三个文件 ? 我来自: perl + fastcgi + nginx搭建 链接失效点我:http://www.ttlsa.com/html/2411.html (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |