Linux 中间件 | Nginx 支持 perl-cgi

本文环境,Amazon Linux release 2,全程用 root 用户。

前提是已经装好了 Nginx,并且有 --with-http_perl_module 模块。没有则参考添加


一、首先确认并安装 perl-FCGI

rpm -qa | grep perl-FCGI
yum install -y perl-FCGI

二、perl-fastcgi 进程管理脚本

/usr/bin/perl-fastcgi.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
    $socket = FCGI::OpenSocket( "/tmp/perl-fastcgi.sock", 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 = <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/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";
       }
 
   }
}

三、perl-fastcgi 启动脚本

/etc/init.d/perl-fastcgi 没有则新建

# 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/perl-fastcgi.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


四、perl-fastcgi 自启动

# perl-fastcgi 脚本添加执行权限
chmod +x /usr/bin/perl-fastcgi.pl

chmod 755 /etc/init.d/perl-fastcgi

systemctl enable perl-fastcgi

五、启动

systemctl start perl-fastcgi

  • Nginx 停止或重启后,需要重新启动 perl-fastcgi


posted @ 2023-03-23 13:20  菜乌  阅读(206)  评论(0编辑  收藏  举报