Lighttpd是一个真正小巧、安全、高效、功能强大的Web服务器,Lighttpd真正重新定义了什么叫Web服务器的性能(Security, speed, compliance, and flexibility -- all of these describe lighttpd (pron.lighty) which is rapidlyredefining efficiency of a webserver;)。
出色的服务器得配备高性能的CGI程序才能发挥出最大的功效。
Lighttpd当然支持传统的CGI程序,但是CGI的一个最大特点是启动慢,每个请求过来后,Lighttpd都会fork一个后台进程来处理这个请求,而fork是个“昂贵”的系统调用,这就限制了整个服务器的性能。
后来业界为了解决CGI的性能问题,提出了fastcgi标准,即整个请求服务子进程一经启动,则以daemon的形式持续驻留在内存中,除了第一次的fork调用外,再没有其他的启动开销,这就极大地提高了服务器响应请求的能力;FastCGI的另一个极其出色的特性是请求服务进程可以远程运行于另外的主机上,Web服务器通过TCP/IP与之同信,当一个请求来时,Web服务器将环境变量和标准输入通过TCP/IP传至另一主机的的请求服务进程,当服务进程处理完请求后,再通过TCP/IP将处理结果传回Web服务器,然后服务器将之传给浏览器,如果在多个主机上配置请求服务进程,则可实现load-balancing,本文不深入讨论这一点。
Lighttpd支持各种编程语言实现的FastCGI,笔者偏爱PERL,以下介绍如何配置Lighttpd使其支持PERL FastCGI,使之达到甚至超过apache+Mod_perl的性能。
本人用Ubuntu 8.04.2系统,Lighttpd的配置文件在 /etc/lighttpd/lighttpd.conf,关于如何详细配置此文件,大家可到其官方网站找到相关资料,本文不求全,但求专,只覆盖Fast CGI的配置部分。
打开/etc/lighttpd/lighttpd.conf文件,在server.modules部分,加入mod_fastcgi一行,以在启动lighttpd时,自动加载此模块,具体配置如下图所示
接下来找到文件中含有$HTTP["remoteip"]的一行,在其中加入Fast CGI的配置选项,如图所示:
Remoteip一行写有"127.0.0.1"表明现在只允许本机访问;在fastcgi.server选项中,socket表示本地Unix domain socket名字,bin-path表示要在后台启动的请求服务程序名。在本例中,我们写了一个简单的PERL脚本lighttpd.fcgi,来充当请求服务程序,来处理任何对.html文件的请求。
lighttpd.fcgi脚本调用CGI::Fast模块,此脚本自启动后就会一直运行,不断处理从Lighttpd传过来的请求,当lighttpd启动后,默认会fork5个lighttpd.fcgi子进程,以轮询方式传递请求到各个lighttpd.fcgi子进程。
lighttpd启动后的进程关系:
root@shawn-laptop:/home/shawn# ps -ef | grep lighttpd | grep -v grep
www-data 14260 1 0 12:41 ? 00:00:00 /usr/sbin/lighttpd -f /etc/lighttpd/lighttpd.conf
www-data 14261 14260 0 12:41 ? 00:00:00 /usr/bin/perl /usr/local/bin/lighttpd.fcgi
www-data 14265 14260 0 12:41 ? 00:00:00 /usr/bin/perl /usr/local/bin/lighttpd.fcgi
www-data 14266 14260 0 12:41 ? 00:00:00 /usr/bin/perl /usr/local/bin/lighttpd.fcgi
www-data 14267 14260 0 12:41 ? 00:00:00 /usr/bin/perl /usr/local/bin/lighttpd.fcgi
接下来看看lighttpd.fcgi如何编写,
root@shawn-laptop:/home/shawn# cat /usr/local/bin/lighttpd.fcgi
#!/usr/bin/perl
use CGI::Fast qw(:standard);
use DBI;
use URI;
#此处的/tmp/fastcgi.socket和lighttpd.conf里面的socket配置一一对应
$ENV{FCGI_SOCKET_PATH} = "/tmp/fastcgi.socket";
$ENV{FCGI_LISTEN_QUEUE} = 100;
$COUNTER = 0;
#在这里,数据库连接只在脚本启动时建立一次,不会在每次请求到来时重新建立,提高了性能
my $dbh = DBI->connect('dbi:Oracle:', 'shawn@192.168.1.100/shzeng', 'hello') || die ;
while (new CGI::Fast) {#这里是关键,如果没有新的请求到来,脚本会阻塞在这里
print header;
print start_html("Fast CGI Rocks");
print
h1("Fast CGI on Lighttpd"),
"Invocation number ",b($COUNTER++),
" PID ",b($$),".",
hr;
my $uri = URI->new( $ENV{REQUEST_URI} );
print br;
print "Requested uri is ",b($uri);
my $sql = 'SELECT * from v$version';#此处查询V$VERSION视图
my $sth = $dbh->prepare($sql);
$sth->execute();
while (my (@s) = $sth->fetchrow_array())
{
print br;
print b($s[0]);
}
print end_html;
}
CGI::Fast和CGI的使用没有什么区别。
现在用浏览器访问随便一个.html文件,看看会有什么显示?
现在可以看到V$VERSION视图里面的内容了。
Lighttpd+mod_fastcgi+PERL+Oracle一应俱全。