Perl + fastcgi + nginx Build
Nginx + fastcgi is the most popular environment in PHP, then Perl will also have fastcgi it, of course, Today to build the next Nginx Perl fastcgi. Performance is no less than PHP, but now the popularity of Web programs PHP is not comparable to Perl, performance is no good, but some of the small features can be considered using Perl's fastcgi to do. Get to the point.
1. Prepare the SOFTWARE environment:
nginx:http://www.nginx.org
Perl: System self-belt
fastcgi:http://www.cpan.org/modules/by-module/fcgi/
1.1 Nginx Installation
This is no longer a detailed description of the ~
1.2 Perl installation
General Linux has its own Perl, you can not install, if you do not, please do:
1.3 perl-fastcgi Installation
# 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 Virtual Host Configuration
server {
listen ;
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
}
}
If you want to change the TCP/IP mode to the socket method, you can modify the fastcgi-wrapper.pl.
$socket = Fcgi::opensocket ("127.0.0.1:8999", 10); #use IP sockets
To
$socket = Fcgi::opensocket ("/var/run/jb51.net.perl.sock", 10); #use IP sockets
3. Configuration Scripts
3.1 fastcgi Listening script
file path:/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's ing perl scripts End () {} BEGIN () {} *core::global::exit = sub {d ie "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"); #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 $;
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 isn't executable by this process.\n";
}
}
}
3.2 fastcgi Self-boot service script:
File path:/etc/rc.d/init.d/perl-fastcgi
File path:/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 Setting Script permissions
# chmod a+x/usr/bin/fastcgi-wrapper.pl
# chmod a+x/etc/rc.d/init.d/perl-fastcgi
4. FASTCGI Test
4.1 Starting Nginx and fastcgi
#/usr/local/nginx-1.4.2/sbin/nginx
#/etc/init.d/perl-fastcgi Start
4.2 Perl Test Files:
file path/data/site/test.jb51.net/test.pl
#!/usr/bin/perl
print "content-type:text/html\n\n";
Print <<EndOfHTML;
5. Access Test
5.1 Access
http://http:test.jb51.net/test.pl, the content indicates OK.
6. Simple Stress test:
6.1 Using TCP/IP mode
Ab-n 1000-c http://test.jb51.net/test.pl
He was too slow to test with 10 concurrent, a total of 100 requests.
6.2 Using the Socket method:
Ab-n 100000-c http://test.jb51.net/test.pl
Oddly, with TCP/IP, there are more than 140 requests per second, while the socket method has 5,800 requests/sec. The gap is not generally large. By the way test the PHP fastcgi, probably request in 3000 (TCP/IP way), 4800 (socket method).
Use of Perl modules
If there is a very small number of places that need to be dynamically displayed for a Web site where most of the content is static, it happens that you know a little bit about Perl, so the combination of Nginx + Perl can be a good solution to the problem. To Nginx support for Perl scripts, you need the following parameters when compiling Nginx:
./configure--with-http_perl_module
If you make the following similar error:
Can ' 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.)
You may need to install Perl-devel perl-extutils-embed on your machine, and for the CentOS system, direct use of Yum is done, for example:
Yum-y Install Perl-devel perl-extutils-embed
There are two ways to use Perl in Nginx, one that is written directly in the configuration file and one that writes the Perl script in an external file, and the second usage is described below.
Suppose the Nginx root directory is perl/lib under the root directory of the Nginx in the directory for the/usr/local/nginx,perl script, and the script name is Test.pm,nginx configured as:
#in httpConfiguration
Perl_modules perl/lib;
Perl_require test.pm;
#in server configuration
Location/user/{
Perl pkg_name::p rocess;
}
The above configuration is to handle all requests from http://servername/user/under the process method defined in the test.pm script.
The contents of the test.pm script are as follows:
Package pkg_name;
Use time::local;
Use Nginx;
Sub process {My
$r = shift;
$r->send_http_header (' text/html; Charset=utf-8 ');
My @arr = Split ('/', $r->uri);
My $username = @arr [2];
if (! $username | | ($username eq "")) {
$username = "Anonymous";
}
$r->print (' Hello, name is: <strong> '. $username. ' </strong> ');
$r->rflush ();
return;
}
1;
__end__
When you visit HTTP://SERVERNAME/USER/NETINGCN, you should be able to see on the Web page:
In addition: When using use Nginx, the following objects can be invoked, you can see the above shift object to the $r, and then you can use $r to invoke those objects:
-
- $r the parameters of the->args– request.
-
- $r->discard_request_body– This parameter is to let Nginx give up request of the body content.
-
- $r->filename– Returns the name of the appropriate request file
-
- $r->has_request_body (function) – if no principal is requested, returns 0, but if the request body exists, the passed function is established and 1 is returned, at the end of the program Nginx the specified processor is invoked.
-
- $r->header_in (header) – Find the information for the request header
-
- $r->header_only– If we just return a response to the head
-
- $r->header_out (header, value)-Sets the header of the response
-
- $r->internal_redirect (URI) – redirects internal to the specified URI, and redirects occur only after the Perl script has been completed. You can use the Header_out (Location ...) method to redirect your browser to itself.
-
- $r->print (args, ...)-Send data to Client
-
- $r->request_body– Get the content submitted by the client (the body parameters may need to modify the Nginx client_body_buffer_size. )
-
- $r->request_body_file-to the customer's body and returns the file name
-
- $r->request_method-Get Request HTTP method.
-
- $r->remote_addr– Gets the IP address of the client.
-
- $r->rflush– to send data to the client immediately
-
- $r->sendfile (file [, displacement [, length])-The contents of the specified file are passed to the client, and optional parameters indicate the offset and length of the data being transmitted only. Accurate delivery takes effect only after the execution of the Perl script has completed. This is called advanced function.
-
- $r->send_http_header (type)-information to add an HTTP header for a response
-
- $r->sleep (milliseconds, Handler) – Set to request that the specified processing and stop processing be used at a specified time, during which Nginx will continue to process other requests, and after a specified time, Nginx will run the installed processing method. Note that you need to pass a reference for the processing method, and you can use $r->variable () to forward the data between the processors.
-
- $r->status (Code)-Sets the response code for HTTP
-
- $r->unescape (text) – Encrypt content using HTTP methods such as%xx
-
- $r->uri– get the requested URL.
-
- $r->variable (name[, value]) – Set the value of a variable