perl + fastcgi + nginx搭建
nginx + fastcgi是php下最流行的一套环境了,那perl会不会也有fastcgi呢,当然有,今天来搭建下nginx下perl的fastcgi.性能方面也不亚于php,但是现在web程序php的流行程度perl无法比拟了,性能再好也枉然,但是部分小功能可以考虑使用perl的fastcgi来搞定.进入正题.
1. 准备软件环境:
nginx:http://www.nginx.org
perl:系统自带
fastcgi:http://www.cpan.org/modules/by-module/FCGI/
1.1 nginx安装
nginx安装过无数次,这边不在重复安装过程,如果你还没有安装nginx并且不知道怎么安装nginx,那么请先参考之前的文章《nginx安装配置》
1.2 perl安装
一般linux都有自带perl,可以不用安装,如果确实没有,请执行:
1
|
# yum install perl
|
1.3 perl-fastcgi安装
1
2
3
4
5
6
7
|
# 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虚拟主机配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
server
{
listen
80
;
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.
1
2
3
|
$
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/fastcgi-wrapper.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
#!/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
=
<
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"
;
}
}
}
|
3.2 fastcgi自启动服务脚本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
文件路径:
/
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 设置脚本权限
1
2
|
# chmod a+x /usr/bin/fastcgi-wrapper.pl
# chmod a+x /etc/rc.d/init.d/perl-fastcgi
|
4. FastCGI测试
1
2
3
|
4.1
启动
nginx与
fastcgi
# /usr/local/nginx-1.4.2/sbin/nginx
# /etc/init.d/perl-fastcgi start
|
4.2 perl测试文件:
文件路径/data/site/test.ttlsa.com/test.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#!/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>"
;
|
5. 访问测试
5.1 访问
http://http:test.ttlsa.com/test.pl,出现内容表示OK.
6. 简单压力测试:
6.1 使用tcp/ip方式
1
|
ab
-
n
1000
-
c
10
http
:
//test.ttlsa.com/test.pl
|
他是在是太慢了,只好用10个并发,共计100个请求来测试.

perl + fastcgi + tcp-ip
6.2 使用socket方式:
1
|
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三个文件
转载请注明出处: http://www.ttlsa.com/html/2411.html
成长的对话版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!