30分钟学会mod_perl
简介
在之前的文章中,我曾展示了一些公司大量部署mod_perl后的令人惊叹的Web性能报告。你可能感到惊讶,但如果你也将你的服务迁移到mod_perl,你完全可以轻松地获得类似的效果。实际上,开始使用mod_perl不需要超过30分钟的时间——这包括在性能良好的机器上编译和配置服务器,并让它运行起来。
在这篇文章中,我将一步步展示安装和配置场景,你将有机会在不阅读任何其他文档的情况下运行基本的静态编译的mod_perl设置。当然,你稍后仍然需要和需要阅读文档,但我认为你将同意我的观点,即能够在不事先了解太多新技术的情况下先尝试一下是非常酷的。
mod_perl的安装已在许多主流Unix平台上进行了测试,所以除非你有非标准系统,否则在构建基本的mod_perl服务器时不应有任何问题。
如果你是Windows用户,那么最简单的方法是使用从http://perl.apache.org/distributions.html提供的二进制包。从同一位置,你可以下载Linux RPM版本和CVS快照。然而,我总是建议从源代码构建mod_perl,并且正如你将很快看到的,这是一件很容易的事情。
安装mod_perl非常简单
让我们从安装过程开始。如果你是一个有经验的Unix用户,那么你不需要对以下命令进行解释。只需复制并粘贴它们,你就可以安装服务器。
我将使用一个%
符号作为shell程序的提示符。
% cd /usr/src
% lwp-download http://www.apache.org/dist/httpd/apache_1.3.20.tar.gz
% lwp-download http://perl.apache.org/dist/mod_perl-1.26.tar.gz
% tar -zvxf apache_1.3.20.tar.gz
% tar -zvxf mod_perl-1.26.tar.gz
% cd mod_perl-1.26
% perl Makefile.PL APACHE_SRC=../apache_1.3.20/src \
DO_HTTPD=1 USE_APACI=1 EVERYTHING=1
% make && make test && make install
% cd ../apache_1.3.20
% make install
这就是全部!
接下来,需要在httpd.conf(Apache配置文件)中添加几行配置,启动服务器,享受mod_perl。
如果你在上述任何步骤中遇到了问题,那么不要绝望——下一节将详细解释每个步骤。
安装mod_perl的详细步骤
如果你没有勇气尝试上一节的步骤,或者你想要在尝试之前了解更多,那么让我们深入了解安装过程的细节。如果你已经按照上一节中的简短场景成功安装了mod_perl,那么你可以跳过这一节,继续下一节。
在继续之前,我应该指出,你必须成为root用户才能将文件安装到受保护区域。如果你没有root权限,那么你可以在你的主目录下安装所有文件。我们将在未来的文章中讨论这种方法的细微差别。我还假设你已经安装了perl和gcc或等效的C编译器。
我假设所有的构建都是在/home/stas/src目录中进行的。因此,我们进入这个目录。
% cd /home/stas/src
现在,我们下载Apache和mod_perl的最新源代码分发版。如果你安装了LWP
模块(也称为libwww,可从CPAN获得),那么你应该有lwp-download
工具,该工具部分模仿你喜欢的浏览器,允许你从互联网上下载文件。你可以使用任何其他方法检索这些文件。只需确保将这两个文件都保存在/home/stas/src目录中,这样就会使你遵循示例安装过程更容易。当然,你可以在文件系统的任何位置安装这两个包。
% lwp-download http://www.apache.org/dist/httpd/apache_1.3.20.tar.gz
% lwp-download http://perl.apache.org/dist/mod_perl-1.26.tar.gz
您可以通过访问以下分发目录来确保您正在下载最新稳定的版本:http://www.apache.org/dist/httpd/ 和 http://perl.apache.org/download/index.html。如您所猜,前者是主要的Apache分发目录,后者是mod_perl的相同目录。
解压两个源文件。您必须解压并解包文件。除了其主要用于打包和解包文件的功能外,GNU tar
工具还能够在使用 -z
选项时解压由 gzip
工具压缩的文件。
% tar -zvxf apache_1.3.20.tar.gz
% tar -zvxf mod_perl-1.26.tar.gz
如果您有一个非GNU tar
工具,那么它很可能无法解压,因此您需要分两步进行。首先,使用以下命令解压软件包:
% gzip -d apache_1.3.20.tar.gz
% gzip -d mod_perl-1.26.tar.gz
然后使用以下命令解包它们:
% tar -xvf apache_1.3.20.tar
% tar -xvf mod_perl-1.26.tar
如果您没有可用的 tar
或 gzip
工具,那么您需要安装它们或使用它们的等效工具。
现在进入mod_perl源分发目录。
% cd mod_perl-1.26
下一步是创建 Makefile。
% perl Makefile.PL APACHE_SRC=../apache_1.3.20/src \
DO_HTTPD=1 USE_APACI=1 EVERYTHING=1
mod_perl接受各种参数,在这个场景中,我们将使用那些将允许您使用mod_perl做几乎所有事情。一旦您对mod_perl了解更多,您将能够调整传递给 Makefile.PL 的参数列表。在未来的文章中,我将介绍所有可用的选项。
perl Makefile.PL ...
的执行将检查依赖项,并告诉您系统缺少哪些所需的软件包。如果您未安装某些Perl软件包,那么您必须在这些软件包安装完成后才能继续。它们全部可在CPAN获得,并且可以轻松下载和安装。
如果您选择使用 CPAN.pm
模块安装mod_perl,那么它将为您安装所有缺少的模块。要这样做,告诉 CPAN.pm
安装 Bundle::Apache
包。
此步骤还将执行Apache源分发目录中的 ./configure
脚本(对您来说绝对透明),该脚本准备Apache构建配置文件。如果您需要向Apache的 ./configure
脚本传递参数,则将它们作为选项传递给 perl Makefile.PL ...
。在未来的文章中,我们将讨论所有可用的选项。
现在您应该使用 make
工具构建 httpd 可执行文件。
% make
此命令准备mod_perl扩展文件,将它们安装在Apache源树中,并通过编译所有必需的文件构建 httpd 可执行文件(即Web服务器本身)。在 make
过程完成后,您将返回到mod_perl源分发目录。
make test
在刚构建的 httpd 可执行文件上执行各种mod_perl测试。
% make test
此命令在非标准端口(8529)上启动服务器,并测试构建的服务器所有部分是否正确运行。如果出现问题,则进程将向您报告。
make install
通过安装mod_perl运行所需的所有Perl文件以及服务器文档(man页面)来完成mod_perl的安装过程。
% make install
您可以使用以下命令的连接方式
% make && make test && make install
这简化了安装过程,因为您不必等待每个命令完成才能开始下一个命令。当第一次为mod_perl安装时,最好分步骤进行。
如果您选择一站式方法,那么您应该知道如果 make
失败,则 make test
和 make install
都不会执行。如果 make test
失败,则 make install
也不会执行。
最后,切换到Apache源分发目录,运行 make install
以创建Apache目录树并安装Apache头文件(*.h)、默认配置文件(*.conf)、httpd 可执行文件和一些其他程序。
% cd ../apache_1.3.20
% make install
请注意,与普通Apache安装一样,此过程不会覆盖先前安装留下的任何配置文件。在安装之前,您不需要备份之前工作的配置文件。
当make install
过程完成后,它将告诉您如何启动一个新建的Web服务器(用于控制服务器的apachectl
实用程序的路径)以及安装的配置文件所在的位置。请记住,或者更好的是,写下这两个路径,因为您将需要这些信息。在我的机器上,两个重要的路径是
/usr/local/apache/bin/apachectl
/usr/local/apache/conf/httpd.conf
到目前为止,我们已经完成了启用mod_perl的Apache的构建和安装。下一步是配置httpd.conf,编写一个小测试脚本,启动服务器并检查测试脚本是否正常工作。
配置和启动mod_perl服务器
首先,我们想确保我们的Apache构建正确,并且可以使用它来服务纯HTML文件。为什么要这样做?为了最小化可能的问题制造者数量,如果我们发现mod_perl不能工作。在您知道Apache可以服务HTML文件后,您就无需再担心它了。如果mod_perl出现问题,您已排除了httpd二进制文件或基本配置损坏的可能性,您知道您可以绑定到已配置服务器监听的端口号,并且您测试的浏览器是正常的。再次提醒,当您第一次安装mod_perl时,应遵循这些指南。
像往常一样配置Apache。在httpd.conf文件中设置Port
、User
、Group
、ErrorLog
和其他指令(记得我要求您在上一节末尾记住该文件的存放位置?)。使用默认值,除非您必须自定义。您需要自定义的值包括ServerName
、Port
、User
、Group
、ServerAdmin
、DocumentRoot
和其他几个。您将发现每个指令之前都有有用的提示。如有疑问,请遵循它们。
编辑完配置文件后,是时候启动服务器了。启动和停止服务器的一种方法是通过使用apachectl
实用程序。您使用以下命令启动服务器
% /usr/local/apache/bin/apachectl start
然后使用以下命令停止它
% /usr/local/apache/bin/apachectl stop
请注意,如果服务器要监听端口号80
或另一个特权端口(<1024)时,您必须以root用户身份启动服务器。
启动服务器后,检查error_log文件(默认位置为/usr/local/apache/logs/error_log),确认服务器确实已启动。不要依赖apachectl
报告的状态。您应该看到类似以下内容
[Thu Jun 22 17:14:07 2000] [notice] Apache/1.3.20 (Unix)
mod_perl/1.26 configured -- resuming normal operations
现在,将您的浏览器指向配置了ServerName
指令的http://localhost/或http://your.server.name/。如果您的Port
指令的值不是80
,则在服务器名后应用此端口号。如果您使用的是端口号8080,则使用http://localhost:8080/或http://your.server.name:8080/测试服务器。您应该看到著名的“``It worked”页面,这是在Apache源树中由make install
安装的index.html
文件。如果您没有看到此页面,则表示有问题,您应检查error_log文件的内容。您可以通过在httpd.conf中的ErrorLog
指令中查找来找到错误日志文件的路径。
如果一切按预期进行,则关闭服务器,用您喜欢的编辑器打开httpd.conf,并将光标移到文件末尾,我们将在此处添加mod_perl配置指令(当然,您可以将它们放在文件的任何位置)。
假设您将所有应由启用mod_perl的服务器执行的脚本放在/home/httpd/perl/目录中,请添加以下配置指令:
Alias /perl/ /home/httpd/perl/
PerlModule Apache::Registry
<Location /perl>
SetHandler perl-script
PerlHandler Apache::Registry
Options ExecCGI
PerlSendHeader On
allow from all
</Location>
保存修改后的文件。
此配置会导致每个以/perl开头的URI都由Apache mod_perl模块处理。它将使用来自Perl模块Apache::Registry
的处理程序。
准备脚本目录
现在创建一个不存在的/home/httpd/perl/目录。为了您和Apache能够读取、写入和执行文件,我们必须设置正确的权限。您可以简单地这样做:
% chmod 0777 /home/httpd/perl
这非常非常不安全,您不应该在生产机器上采用这种方法。如果您只是想尝试事物并且想尽可能少地遇到障碍,这足够了。一旦您了解了事物是如何工作的,您应该调整Apache所服务的文件的权限。在未来文章中,我们将讨论设置适当的文件权限。
Apache::Registry脚本“mod_perl规则”
如您所知,mod_perl允许您重用以前在mod_cgi下使用的Perl编写的CGI脚本。因此,我们的第一个测试脚本可以非常简单:
mod_perl_rules1.pl
------------------
print "Content-type: text/plain\r\n\r\n";
print "mod_perl rules!\n";
将此脚本保存到/home/httpd/perl/mod_perl_rules1.pl文件中。注意,mod_perl不需要shebang行,但您可以保留它。所以下面的脚本也可以使用:
mod_perl_rules1.pl
------------------
#!/usr/bin/perl
print "Content-type: text/plain\r\n\r\n";
print "mod_perl rules!\n";
当然,您可以使用Apache Perl API编写相同的脚本
mod_perl_rules2.pl
------------------
my $r = shift;
$r->send_http_header('text/plain');
$r->print("mod_perl rules!\n");
将此脚本保存到/home/httpd/perl/mod_perl_rules2.pl文件中。
现在使这两个脚本对服务器可执行和可读。请记住,当您从shell执行脚本时,它们是由您登录的用户名执行的。当您通过发出请求来运行脚本时,Apache需要能够读取和执行它们。因此,我们将脚本设置为对每个人可读和可执行
% chmod 0755 /home/httpd/perl/mod_perl_rules1.pl \
/home/httpd/perl/mod_perl_rules2.pl
如果您不希望其他用户能够读取您的脚本,那么您应该将自己添加到Web服务器运行的组名(由Group
指令定义)中,然后使脚本属于该组并调整权限。例如,在我的机器上,我在httpd组下运行服务器,我是唯一一个在该组中的人,所以我可以这样做:
% chown stas.httpd /home/httpd/perl/mod_perl_rules1.pl \
/home/httpd/perl/mod_perl_rules2.pl
% chmod 0750 /home/httpd/perl/mod_perl_rules1.pl \
/home/httpd/perl/mod_perl_rules2.pl
第一个命令使文件属于httpd组,第二个设置适当的执行和读取权限。
这是安全的,假设您为您的服务器有一个专用的组名。
此外,请记住,所有指向脚本的目录都应该由服务器可读和可执行。
您可以从命令行测试mod_perl_rules1.pl,因为本质上它是一个常规的Perl脚本。
% perl /home/httpd/perl/mod_perl_rules1.pl
您应该看到以下输出:
mod_perl rules!
您无法通过从命令行执行它来测试第二个脚本,因为它使用了仅在mod_perl服务器内部运行的mod_perl API。
确保服务器正在运行,并使用您喜欢的浏览器发出这些请求
http://localhost/perl/mod_perl_rules1.pl
http://localhost/perl/mod_perl_rules2.pl
在这两种情况下,您都会在以下响应中看到:
mod_perl rules!
如果您看到了它——恭喜!您有一个工作的mod_perl服务器。
如果您使用的是8080端口而不是80,那么您应该在URL中使用此数字
http://localhost:8080/perl/mod_perl_rules1.pl
http://localhost:8080/perl/mod_perl_rules2.pl
localhost
方法仅在浏览器在运行服务器的同一台机器上时才有效。如果不是,则使用实际的服务器名称进行此测试。例如
http://your.server.name/perl/mod_perl_rules1.pl
如果出现任何问题,请参阅error_log文件以获取错误报告。
现在是将您的CGI脚本从/somewhere/cgi-bin目录移到/home/httpd/perl/目录,并看到它们在新配置的基础URL(/perl/)请求时运行得更快。如果您以前是通过/cgi-bin/test.pl访问脚本的,那么现在将通过/perl/test.pl访问它。
您的一些脚本可能无法立即工作,需要一些微调甚至部分重写才能与 mod_perl 正确配合。如果您不进行草率编程,那么脚本将无需修改即可运行。
如果您的脚本出现问题,一个好的方法是将其中的 Apache::Registry
替换为 Apache::PerlRun
,因为它可以执行编写得非常糟糕的脚本。请在 httpd.conf 中放置以下配置指令,并重新启动服务器
PerlModule Apache::PerlRun
<Location /perl>
SetHandler perl-script
PerlHandler Apache::PerlRun
Options ExecCGI
PerlSendHeader On
allow from all
</Location>
现在您的脚本应该可以工作了,除非它们包含 mod_perl 不接受的内容。我们将在未来的文章中讨论这些细微差别。
“mod_perl 规则” Apache Perl 模块
mod_perl 是关于运行脚本和处理器。虽然我已经开始使用脚本介绍 mod_perl,因为如果您之前编写过 CGI 脚本,这将更容易,但 mod_perl 的更高级使用是编写处理器。但不要担心。正如您一会儿将看到的,编写处理器几乎和编写脚本一样简单。
要创建一个 mod_perl 处理器模块,我只需将用于脚本的代码包装在一个 handler
子例程中,在子例程成功完成后向服务器返回状态语句,并在代码顶部添加一个包声明。
就像脚本一样,您可以使用您可能熟悉的 CGI API
ModPerl/Rules1.pm
----------------
package ModPerl::Rules1;
use Apache::Constants qw(:common);
sub handler{
print "Content-type: text/plain\r\n\r\n";
print "mod_perl rules!\n";
return OK;
}
1; # satisfy require()
或者允许您通过提供在常规 Perl 下不可用的 API 更亲密地与 Apache 核心交互的 Apache Perl API。当然,在我的简单示例中,使用任何一种方法都可以,但当你需要使用 API 时,应使用此版本的代码。
ModPerl/Rules2.pm
----------------
package ModPerl::Rules2;
use Apache::Constants qw(:common);
sub handler{
my $r = shift;
$r->send_http_header('text/plain');
print "mod_perl rules!\n";
return OK;
}
1; # satisfy require()
在 @INC
目录中的一个目录下创建一个名为 ModPerl 的目录(例如 /usr/lib/perl5/site_perl/5.005),并将 Rules1.pm 和 Rules2.pm 放入其中,这些文件应包含上面示例中的代码。
要找出 @INC
目录是什么,执行
% perl -le 'print join "\n", @INC'
在我的机器上,它报告
/usr/lib/perl5/5.6.1/i386-linux
/usr/lib/perl5/5.6.1
/usr/lib/perl5/site_perl/5.6.1/i386-linux
/usr/lib/perl5/site_perl/5.6.1
/usr/lib/perl5/site_perl
.
现在将以下片段添加到 httpd.conf 中,以配置 mod_perl 在请求 mod_perl_rules1 时执行 ModPerl::Rules::handler
子例程
PerlModule ModPerl::Rules1
<Location /mod_perl_rules1>
SetHandler perl-script
PerlHandler ModPerl::Rules1
</Location>
现在您可以发出一个请求到
http://localhost/mod_perl_rules1
并且就像我们的 mod_perl_rules.pl 脚本一样,您将看到
mod_perl rules!
作为响应。
要测试第二个模块 <ModPerl::Rules2>,添加相同的配置,将所有 1 替换为 2
PerlModule ModPerl::Rules2
<Location /mod_perl_rules2>
SetHandler perl-script
PerlHandler ModPerl::Rules2
</Location>
要测试,请使用 URI
http://localhost/mod_perl_rules2
关于 mod_perl 我需要知道这些吗?
显然,您接下来会问的问题是:“这是关于 mod_perl 我需要知道的所有吗?”。
答案是:“是,也不是”。
“是”的部分
- 就像 Perl 一样,您只需要对 mod_perl 有很少的了解就能做真正酷的事情。所展示的设置允许您以更快的速度运行您的访客计数器和留言簿,并让您的朋友惊讶,通常无需更改代码的任何一行。
“不是”的部分
将留言簿的响应时间提高 50 倍是很好的,但当一个包含数千个并发用户的重型服务部署时,考虑到类似 Web 服务之间的高级别竞争,几毫秒的延迟可能会让您失去一个客户,可能还有很多。
当然,当您测试单个脚本并且您是唯一用户时,您并不真正关心从响应时间中挤出另一毫秒,但当这些毫秒在生产站点上累积,有数百个用户同时向您网站上的各种脚本生成请求时,这成为一个真正的问题。现在的用户并不仁慈——如果还有另一个提供相同服务但速度略快一点的网站,那么他们很可能会去那里。
在未加载的机器上测试脚本可能会产生误导,一切看起来都如此完美。但当你把它们转移到生产机器上时,它们的性能并不像在开发环境中那样好。很多时候,你只是因为繁忙的服务而耗尽内存。你需要学习如何优化代码以使用更少的内存,以及如何实现内存共享。
调试是人们不愿谈论的话题,因为这个过程可能会很繁琐。如果你认为自己是一名Web程序员,那么学习如何使调试过程更加简单和高效是必不可少的。这项任务在调试CGI脚本时尤其不是那么直接,而当使用mod_perl时,问题变得更加复杂——除非你了解如何操作,否则它突然变得容易。
参考文献
Apache网站URL: http://www.apache.org/
mod_perl网站URL: http://perl.apache.org/
CPAN是综合Perl归档网络。主站URL是 http://cpan.org/。CPAN在全球超过100个站点进行了镜像。(http://cpan.org/SITES.html)当与数据库一起使用时,mod_perl有许多在mod_cgi下不可用的功能。其中最重要的包括持久连接。
你必须知道如何让你的服务不间断运行,并且能够在出现问题时快速恢复。
最后,最重要的是Apache-Perl API,它允许你对收到的请求做任何事情,甚至干预请求处理的每个阶段。这给了你极大的灵活性,并允许你创建用普通的mod_cgi无法想象的东西。
关于mod_perl和Web编程还有许多其他东西需要学习。在未来文章中,我将详细讨论所有这些问题。
致谢
非常感谢Eric Cholet对本文章的审阅。
标签
反馈
这篇文章有问题吗?请通过在GitHub上打开问题或拉取请求来帮助我们。