Apache mod_perl 构建并运行示例 Perl Web 应用指南
在 Apache/2.4.52 + mod_perl 2.0.12 环境下,从零编写 Perl 处理器 Hello.pm 并配置 Apache,构建并验证一个输出 Hello from mod_perl! 的示例 Perl Web 应用
Apache mod_perl 构建并运行示例 Perl Web 应用指南
目标:在 Apache/2.4.52 + mod_perl 2.0.12 环境下,从零编写一个 Perl 处理器(Hello.pm)并完成 Apache 配置,使应用响应 HTTP 请求,最终通过 curl 验证输出
Hello from mod_perl!;已在 Ubuntu 22.04.5 实测通过。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- Apache HTTP Server:Apache/2.4.52 (Ubuntu)
- Perl:v5.34.0
- mod_perl:2.0.12(apt 包
libapache2-mod-perl22.0.12-1build1) - 应用目录:
/var/www/perl/ - 访问地址:
http://localhost/hello - 服务控制:
apache2ctl -k restart(本环境未启用 systemd 服务托管) - 示例账号:root
二、示例应用结构
| 文件/路径 | 说明 |
|---|---|
/var/www/perl/Hello.pm | Perl 处理器源码,响应 /hello 请求 |
/etc/apache2/sites-available/000-default.conf | 默认站点配置,追加 <Location /hello> 段 |
/etc/apache2/conf-available/perl-switches.conf | 全局 @INC 搜索路径配置(PerlSwitches -I/var/www/perl) |
/var/log/apache2/access.log | 访问日志 |
/var/log/apache2/error.log | 错误日志(含启动横幅与 perl 错误) |
三、前置条件
- 已安装
apache2、libapache2-mod-perl2、perl、curl(安装见《Ubuntu 22.04 安装 Apache mod_perl 指南》)。 - mod_perl 模块已加载:
apache2ctl -M | grep -i perl
回显:
perl_module (shared)
四、编写 Perl 处理器(Hello.pm)
4.1 创建应用目录并写入源码
mkdir -p /var/www/perl
cat > /var/www/perl/Hello.pm <<'EOF'
package Hello;
use strict;
use Apache2::RequestRec ();
use Apache2::RequestIO ();
use Apache2::Const -compile => qw(OK);
sub handler {
my $r = shift;
$r->content_type('text/html');
$r->print("Hello from mod_perl!");
return Apache2::Const::OK;
}
1;
EOF
4.2 语法检查
perl -c /var/www/perl/Hello.pm
回显:
/var/www/perl/Hello.pm syntax OK
4.3 源码要点
package Hello;:包名即处理器名,PerlResponseHandler Hello会调用其中的handler子例程。use Apache2::RequestRec ();:提供请求对象$r(含content_type等方法)。use Apache2::RequestIO ();:提供$r->print()输出方法。use Apache2::Const -compile => qw(OK);:预编译常量OK(即 HTTP 正常返回,数值 0)。sub handler:mod_perl 处理器约定入口,接收请求对象、输出正文并返回Apache2::Const::OK。- 末尾
1;:Perl 模块文件必须返回真值。
五、Apache 配置
5.1 启用 perl 模块
a2enmod perl
回显:
Module perl already enabled
5.2 添加 Location 配置
在 /etc/apache2/sites-available/000-default.conf 的 <VirtualHost> 内追加:
<Location /hello>
SetHandler perl-script
PerlResponseHandler Hello
PerlOptions +ParseHeaders
</Location>
逐条说明:
SetHandler perl-script:让该路径的请求交给 mod_perl 的perl-script处理器。PerlResponseHandler Hello:指定响应阶段处理器为Hello包(即/var/www/perl/Hello.pm)。PerlOptions +ParseHeaders:启用响应头解析;本例处理器直接设置content_type并打印正文,配合该选项可正确输出。
5.3 配置 @INC 搜索路径(关键)
mod_perl 默认 @INC 不含 /var/www/perl,首次访问会报 Can't locate Hello.pm in @INC(HTTP 500)。需用 PerlSwitches(仅启动时生效)追加搜索路径:
cat > /etc/apache2/conf-available/perl-switches.conf <<'EOF'
PerlSwitches -I/var/www/perl
EOF
a2enconf perl-switches
⚠️ 注意:
PerlSwitches只在 Apache 启动时生效,修改后必须完整重启,reload 不生效。
六、启动服务并验证
6.1 配置语法检查
apache2ctl configtest
回显(AH00558 为未设置 ServerName 的提示性警告,非致命):
AH00558: apache2: Could not reliably determine the server's fully qualified domain name. Set the 'ServerName' directive globally to suppress this message
Syntax OK
6.2 完整重启
apache2ctl -k restart
回显(要点):
httpd not running, trying to start
rc=0
6.3 curl 验证
curl -s -i http://localhost/hello
回显:
HTTP/1.1 200 OK
Date: Sun, 11 Oct 2026 11:33:53 GMT
Server: Apache/2.4.52 (Ubuntu)
Vary: Accept-Encoding
Transfer-Encoding: chunked
Content-Type: text/html
Hello from mod_perl!
只看状态码:
curl -s -o /dev/null -w "HTTP %{http_code}\n" http://localhost/hello
回显:
HTTP 200
6.4 日志确认
访问日志 /var/log/apache2/access.log:
127.0.0.1 - - [11/Oct/2026:11:33:53 +0000] "GET /hello HTTP/1.1" 200 195 "-" "curl/7.81.0"
错误日志 /var/log/apache2/error.log(启动横幅含 mod_perl 版本):
[Sun Oct 11 11:09:51.101256 2026] [mpm_event:notice] [pid 3478] AH00489: Apache/2.4.52 (Ubuntu) mod_perl/2.0.12 Perl/v5.34.0 configured -- resuming normal operations
七、目录与文件说明
| 路径 | 说明 |
|---|---|
/var/www/perl/Hello.pm | 应用源码(本次示例唯一代码文件) |
/etc/apache2/mods-available/perl.load | perl 模块加载文件:LoadModule perl_module /usr/lib/apache2/modules/mod_perl.so |
/etc/apache2/conf-available/perl-switches.conf | 全局 @INC 扩展配置 |
/usr/lib/x86_64-linux-gnu/perl5/5.34/Apache2/ | 包自带的 Apache2:: Perl 模块(RequestRec/RequestIO/Const 等) |
/usr/lib/apache2/modules/mod_perl.so | mod_perl 动态库(245208 字节) |
/usr/share/doc/libapache2-mod-perl2 | 包自带文档目录 |
八、常用运维命令
# 完整重启(PerlSwitches 等启动期配置变更后必须使用)
apache2ctl -k restart
# 配置语法检查
apache2ctl configtest
# 查看已加载模块(确认 perl_module)
apache2ctl -M | grep -i perl
# 跟踪错误日志
tail -f /var/log/apache2/error.log
九、常见问题(FAQ)
Q1:首次访问 /hello 报 HTTP 500,error.log 提示 failed to resolve handler 'Hello': Can't locate Hello.pm in @INC?
自定义模块目录不在 mod_perl 默认 @INC 中。修复:创建 /etc/apache2/conf-available/perl-switches.conf 写入 PerlSwitches -I/var/www/perl,a2enconf perl-switches 后完整重启(apache2ctl -k restart),reload 不生效。
Q2:修改了 PerlSwitches 但 reload 后仍报 500?
PerlSwitches 仅在 Apache 启动时生效,必须完整重启(apache2ctl -k restart)。
Q3:改完 Hello.pm 后访问仍是旧内容?
mod_perl 默认在首次请求时按 @INC 加载模块。开发期改完代码建议完整重启,或改用 PerlModule Hello 启动时预加载。
Q4:返回 500 但 error.log 没有 perl:error 记录?
先 apache2ctl configtest 确认配置语法;再检查 <Location> 段缩进、SetHandler perl-script 拼写与 PerlResponseHandler 包名是否与 package Hello; 一致。
Q5:如何确认 mod_perl 已生效?
访问日志出现 "GET /hello HTTP/1.1" 200 195,且 error.log 启动横幅显示 Apache/2.4.52 (Ubuntu) mod_perl/2.0.12 Perl/v5.34.0。
十、参考链接
- mod_perl 官方文档:https://perl.apache.org/docs/2.0/user/
- Apache2::RequestRec / RequestIO 文档:https://perl.apache.org/docs/2.0/api/
- Apache HTTP Server 2.4 配置说明:https://httpd.apache.org/docs/2.4/