对于老式的CGI技术,姑且不管它的稳定性和安全性如何,但是每次请求就launch一个进程,对资源的消耗是可想而知的,尤其是在当前WWW信息爆炸时期。因此,近些年出现了一些取代方案,比如FastCGI, ASP, JSP, PHP...
这些技术在响应速度上有了很大提升,而且随着这些年的发展,它们的稳定性和安全性可以和CGI媲美。但是,试着考虑下面的问题,它们的支持又如何呢?
(1)我有一个Mission Critical的应用,要求响应速度可达到相当于请求静态页面的程度,比如每秒800个并发用户1800次请求;
(2)我需要对某个目录下的所有页面自动添加一些HTTP Header信息;
(3)我需要安装字符集编码过滤器,以对所有请求或者发出去的信息进行编码;
(4)我需要控制Web服务器的通信过程,比如把N次请求作为一次事务进行处理,而不是Stateless的离散请求
......
是的,就我个人而言,面对的困惑太多了,我需要知道解决问题的更好方法。CGI是无法满足需求的,CGI规范限制了它的功能范围。一些动态脚本技术,比如PHP,好像也不大适用。虽然以模块加载的PHP在性能上有了提升,但是Script脚本在性能方面总归打了折扣。而且PHP在处理一些服务控制方面的功能时捉襟见肘。
但是,事情并没有上文说的那么灰暗。对于每一种现代WWW服务器,都提供了扩展解决方案。比如IIS的ISAPI,Apache的扩展模块, Tomcat的Servlet。它们有一个共同点,就是应用和服务紧密耦合。我在努力尝试这些技术,其中包括扩展Apache的mod_perl。
mod_perl是用Perl开发Apache扩展模块的编程接口,这里介绍一下它在Windows下的安装和配置,至于该做如何评论,留给大家吧。
首先需要确保已经正确安装了Perl和MSVC 6.0,假设Perl安装在C:\Perl下,然后遵循下文的步骤。
(1)安装Apache 1.3.29
参看本站的 /php/ 教程。
(2)编译mod_perl源代码
从http://perl.apache.org/download/source.html#Stable_Source_Distribution下载 mod_perl-1.29.tar.gz,解压到C:\mod_perl。
打开控制台窗口,运行VC自带的命令VCVARS32.BAT,以设置编译环境。
切换到C:\mod_perl目录,运行如下命令:
C:\mod_perl> perl Makefile.PL
C:\mod_perl> nmake
这将Make好mod_perl中Perl相关文件。
启动VC,新建立一个空的Win32 Dynamic Library项目mod_perl,添加C:\mod_perl\src\modules\perl下的所有文件和C:\mod_perl\src\modules\win32\mod_perl.def。
设置输出为mod_perl.so,增加头文件搜寻路径C:\Apache\include,C:\Perl\lib\Core。增加库文件ApacheCore.lib(在Apache的安装目录)和perl58.lib(在Perl的安装目录)。
然后设置Project -> Settings -> [C/C++] -> Category: [Code Generation] ->
Use runtime library: [Multithreaded DLL]。
编译后会生成 mod_perl.so。有可能编译的过程会报错,比如我编译的时候出现 undefined NULL,在报错的文件顶部添加一行 #define NULL 0就过去了。还有一个文件报 非预料的文件结尾错误,经查找发现是一个文本串书写成了两行(搞不懂为什么会弄成这样,Aaaaaaaaaaaa)。
把生成的mod_perl.so拷贝到C:\mod_perl\t\modules下,然后回到控制台命令行,运行如下命令:
C:\mod_perl> nmake test
C:\mod_perl> nmake install
这将把mod_perl中Perl相关模块安装到C:\Perl库中去。
拷贝mod_perl.so到Apache的modules目录。
(3)配制Apache
修改C:\Apache\conf\httpd.conf,在末尾添加
LoadModule perl_module modules/mod_perl.so
AddModule mod_perl.c
Include conf/perl.conf
然后在C:\Apache\conf\下建立一个文件perl.conf,内容如下:
PerlRequire conf/startup.pl
PerlFreshRestart On
这里startup.pl是初始化脚本,在C:\Apache\conf目录里,内容如下:
#!C:/Perl/bin/perl.exe
# modify the include path before we do anything else
BEGIN {
use Apache ();
use lib Apache->server_root_relative('lib/perl');
}
# commonly used modules
use Apache::Registry ();
use Apache::Constants();
use CGI qw(-compile :all);
use CGI::Carp ();
# put any other common modules here
# use Apache::DBI ();
# use LWP ();
# use DB_File ();
1;
这里把mod_perl调用的库设置在C:\Apache\lib\perl下,这是以后我们编写Perl扩展模块的保存路径。
(4)测试第一个Apache扩展模块
在C:\Apache\lib\perl\Apache建立一个文件Hello.pm,内容如下:
package Apache::Hello;
use strict;
use Apache::Constants qw(:common);
sub handler {
my $r = shift;
$r->content_type('text/html');
$r->send_http_header;
my $host = $r->get_remote_host;
$r->print(<
Hello Here
Hello $host
Who would take this book seriously if the first example didn't
say "hello world"?
END
return OK;
}
1;
修改C:\Apache\conf\perl.conf,添加
SetHandler perl-script
PerlHandler Apache::Hello
重新启动Apache,在浏览器中输入 http://localhost/hello/world
你是否看到了想要的东西了呢?
参考资料:
http://perl.apache.org/docs/1.0/os/win32/install.html
《Writing Apache Modules with Perl and C》,OReilly

