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_perlApache mod_perl2026/10/11

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-perl2 2.0.12-1build1)
  • 应用目录:/var/www/perl/
  • 访问地址:http://localhost/hello
  • 服务控制:apache2ctl -k restart(本环境未启用 systemd 服务托管)
  • 示例账号:root

二、示例应用结构

文件/路径说明
/var/www/perl/Hello.pmPerl 处理器源码,响应 /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.loadperl 模块加载文件: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.somod_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。

十、参考链接