So verwenden Sie Nginx als Perl-Programmserver und sein Perl-Modul unter Linux

PHPz
Freigeben: 2023-05-16 23:25:51
nach vorne
1020 Leute haben es durchsucht

perl + fastcgi + nginx搭建

nginx + fastcgi是php下最流行的一套环境了,那perl会不会也有fastcgi呢,当然有,今天来搭建下nginx下perl的fastcgi.性能方面也不亚于php,但是现在web程序php的流行程度perl无法比拟了,性能再好也枉然,但是部分小功能可以考虑使用perl的fastcgi来搞定.进入正题.
1. 准备软件环境:

nginx
perl:系统自带
fastcgi

1.2 perl安装
一般linux都有自带perl,可以不用安装,如果确实没有,请执行:

# yum install perl
Nach dem Login kopieren

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
Nach dem Login kopieren

2. nginx虚拟主机配置

server {
 
  listen  80;
  server_name test.jb51.net;
  #access_log /data/logs/nginx/test.jb51.net.access.log main;
 
  index index.html index.php index.html;
  root /data/site/test.jb51.net;
 
  location / 
  {
 
  }
 
  location ~ \.pl$ 
  {
   include fastcgi_params;
   fastcgi_pass 127.0.0.1:8999;
   #fastcgi_pass unix:/var/run/jb51.net.perl.sock;
   fastcgi_index index.pl;
  }
}
Nach dem Login kopieren

如果想把tcp/ip方式改为socket方式,可以修改fastcgi-wrapper.pl.

$socket = fcgi::opensocket( "127.0.0.1:8999", 10 ); #use ip sockets
Nach dem Login kopieren

改为

$socket = fcgi::opensocket( "/var/run/jb51.net.perl.sock", 10 ); #use ip sockets
Nach dem Login kopieren

3. 配置脚本

3.1 fastcgi监听脚本
文件路径:/usr/bin/fastcgi-wrapper.pl

#!/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 "fakeexit\nrc=".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/plain\r\n\r\n");
      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 = ) { 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/plain\r\n\r\n");
    print "error: no such cgi app - $req_params{script_filename} may not ";
    print "exist or is not executable by this process.\n";
   }
 
  }
}
Nach dem Login kopieren

3.2 fastcgi自启动服务脚本:

文件路径:/etc/rc.d/init.d/perl-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
Nach dem Login kopieren

3.3 设置脚本权限

# chmod a+x /usr/bin/fastcgi-wrapper.pl
# chmod a+x /etc/rc.d/init.d/perl-fastcgi
Nach dem Login kopieren


4. fastcgi测试
4.1 启动nginx与fastcgi

# /usr/local/nginx-1.4.2/sbin/nginx
# /etc/init.d/perl-fastcgi start
Nach dem Login kopieren

4.2 perl测试文件:
文件路径/data/site/test.jb51.net/test.pl

#!/usr/bin/perl
 
print "content-type:text/html\n\n";
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>";
Nach dem Login kopieren

5. 访问测试

5.1 访问
http://http:test.jb51.net/test.pl,出现内容表示ok.

6. 简单压力测试:
6.1 使用tcp/ip方式

ab -n 1000 -c 10 http://test.jb51.net/test.pl
Nach dem Login kopieren

他是在是太慢了,只好用10个并发,共计100个请求来测试.

So verwenden Sie Nginx als Perl-Programmserver und sein Perl-Modul unter Linux

6.2 使用socket方式:

ab -n 100000 -c 500 http://test.jb51.net/test.pl
Nach dem Login kopieren

So verwenden Sie Nginx als Perl-Programmserver und sein Perl-Modul unter Linux

很奇怪,使用tcp/ip方式,每秒就140多个请求,而使用socket方式却有5800个请求/秒。差距不是一般的大。顺便测试了一下php的fastcgi,大概请求在3000(tcp/ip方式),4800(socket方式)。

perl模块的使用
如果对于一个绝大部分内容是静态的网站,只有极少数的地方需要动态显示,碰巧你又了解一点perl知识,那么nginx + perl的结合就能很好解决问题。要想nginx支持perl脚本,在编译nginx时候需要如下参数:

./configure --with-http_perl_module
Nach dem Login kopieren

如果make时候出现如下类似错误:

can&#39;t locate extutils/embed.pm in @inc (@inc contains: /usr/lib/perl5/5.10.0/i386-linux-thread-multi /usr/lib/perl5/5.10.0 /usr/local/lib/perl5/site_perl/5.10.0/i386-linux-thread-multi /usr/local/lib/perl5/site_perl/5.10.0 /usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.10.0 /usr/lib/perl5/vendor_perl /usr/local/lib/perl5/site_perl .)
Nach dem Login kopieren

你的机器上可能需要安装perl-devel perl-extutils-embed,对于centos系统,直接使用yum搞定,例如:

yum -y install perl-devel perl-extutils-embed
Nach dem Login kopieren

nginx中使用perl有两种方法,一种是直接在配置文件写,还有一种是把perl脚本写在外部文件中,下面主要介绍一下第二种用法。
假设nginx的根目录为/usr/local/nginx,perl脚本存放的目录为nginx的根目录下的perl/lib下,脚本名字为test.pm,nginx配置为:

#位于http配置中
 perl_modules perl/lib;
 perl_require test.pm;
 
#位于server配置中
 location /user/ {
 perl pkg_name::process;
 }
Nach dem Login kopieren

上述配置是把所有来自http://servername/user/下的请求交由test.pm脚本中定义的process方法来处理。
test.pm脚本的内容如下:

package pkg_name;
 
use time::local;
use nginx;
 
sub process {
 my $r = shift;
 
 $r->send_http_header(&#39;text/html; charset=utf-8&#39;);
 my @arr = split(&#39;/&#39;, $r->uri);
 my $username = @arr[2];
 
 if (!$username || ($username eq "")) {
 $username = "anonymous";
 }
 
 $r->print(&#39;hello, you name is : <strong>&#39; . $username . &#39;</strong>&#39;);
 $r->rflush();
 return;
}
 
1;
__end__
Nach dem Login kopieren

当你访问http://servername/user/netingcn,你应该可以在网页上看到:

hello, you name is : netingcn
Nach dem Login kopieren

另外:当使用 use nginx 时,会有如下的对象可以调用,可以看到上面 shift 一个对象到 $r 上,然后就可以用 $r 调用那些对象了:

  • $r->args – 请求的参数 .

  • $r->discard_request_body – 这个参数是让 nginx 放弃 request 的 body 的内容.

  • $r->filename – 返回合适的请求文件的名字

  • $r->has_request_body(function) – 如果没有请求主体,返回0,但是如果请求主体存在,那么建立传递的函数并返回1,在程序的最后,nginx将调用指定的处理器.

  • $r->header_in(header) – 查找请求头的信息

  • $r->header_only – 如果我们只要返回一个响应的头

  • $r->header_out(header, value) – 设置响应的头

  • $r->internal_redirect(uri) – 使内部重定向到指定的uri,重定向仅在完成perl脚本后发生.可以使用 header_out(location….的方法来让浏览器自己重定向

  • $r->print(args, …) – 发送数据给客户端

  • $r->request_body – 得到客户端提交过来的内容 (body 的参数,可能需要修改 nginx 的 client_body_buffer_size. )

  • $r->request_body_file —给客户的 body 存成文件,并返回文件名

  • $r->request_method — 得到请求 http method.

  • $r->remote_addr – 得到客户端的 ip 地址.

  • $r->rflush – Daten sofort an den Client senden

  • $r->sendfile(file [, Verschiebung [, Länge] ) – Den Inhalt der angegebenen Datei an den Client senden, optionale Parameter Gibt an, dass nur der Offset und die Länge der Daten übertragen werden. Die genaue Übertragung wird erst wirksam, nachdem das Perl-Skript ausgeführt wurde. Dies ist die sogenannte erweiterte Funktion

  • $r->send_http_header(type) – Add a Antwort-HTTP-Header-Informationen

  • $r->sleep(milliseconds, handler) – Legen Sie fest, dass die Anforderung die angegebene Verarbeitungsmethode verwendet und die Verarbeitung zum angegebenen Zeitpunkt stoppt. Während dieses Zeitraums verarbeitet Nginx weiterhin andere Anforderungen Zur angegebenen Zeit führt Nginx die installierte Verarbeitungsmethode aus. Um Daten zwischen Prozessoren weiterzuleiten, können Sie $r->variable() verwenden ;status(code) – HTTP-Antwortcode festlegen

  • $r->unescape(text) – HTTP-Methode verwenden, um Inhalte wie %xx

  • $r->uri zu verschlüsseln – Angeforderte URL abrufen.

  • $r ->variable(name[, value]) – Legen Sie den Wert der Variablen fest

Das obige ist der detaillierte Inhalt vonSo verwenden Sie Nginx als Perl-Programmserver und sein Perl-Modul unter Linux. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:yisu.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage