【问题标题】:Does mod_perl cache modules loaded dynamically?mod_perl 缓存模块是否动态加载?
【发布时间】:2012-02-09 17:43:31
【问题描述】:

我先做了一些搜索,但还没有找到满意的答案(如果这是一个重复的问题,我很抱歉——或者更糟糕的是,一个愚蠢的问题)......

动态加载的 Perl 模块,例如 this question 答案中包含的那些(相关代码复制如下)是否被 mod_perl 正确缓存以备将来使用?

my $module = 'My::Module';

eval {
    (my $file = $module) =~ s|::|/|g;
    require $file . '.pm';
    $module->import();
    1;
} or do {
    my $error = $@;
    # ...
};

在上面的例子中,如果一个子例程在将来类似地尝试需要它(至少以 mod_perl 通常用于包缓存的任何方式),在这个调用之后,“My::Module”是否会被 mod_perl 缓存以供将来使用?

希望这个问题有点清楚,如果需要任何澄清,请告诉我。谢谢。

【问题讨论】:

    标签: perl apache mod-perl


    【解决方案1】:

    是的,它会被 perl 自己缓存。 (mod_perl 关于这个主题的任务只是将脚本翻译成可缓存的包,并注意保持 Perl 始终运行而不是在响应完成时退出。)

    不过,您必须了解这在各种 httpd MPM 中是如何发挥作用的。请注意,进程具有独立的 %INC。使用 prefork,以下示例程序将需要为每个新子动态加载模块。这意味着前几个请求将比平均速度慢,因为它们是循环处理的。模块被缓存,直到孩子退出,因为它已达到其最大请求阈值,然后每个新的孩子都必须再次加载。

    package Foo;
    use Apache2::Const -compile => qw(OK);
    use Apache2::RequestIO qw();
    use Apache2::RequestRec qw();
    use Data::Dumper qw(Dumper);
    
    sub handler {
        my ($r) = @_;
    
        $r->content_type('text/plain');
        $Data::Dumper::Sortkeys = 1;
        $r->print(Dumper \%INC);
    
        my $module = 'Template';
        eval {
            (my $file = $module) =~ s|::|/|g;
            require $file . '.pm';
            $module->import();
            1;
        } or die $@;
    
        $r->print(Dumper \%INC);
        return Apache2::Const::OK;
    }
    
    1;
    

    通常建议通过在分叉发生之前在服务器启动时加载您可能已经需要的任何模块来优化性能。服务器硬件应该有足够的内存来使模块延迟加载的权衡变得不必要。

    【讨论】:

    • 非常感谢您的深刻回答。这正是我一直在寻找的。沿着类似的思路,是否有任何充分的理由(除了 Apache 启动时间)预加载在任意子进程的生命周期中可能使用的所有模块?再次感谢,非常有帮助的答案。
    • 我能想到的另一个原因:试图加载相互不兼容的模块。还没有发生在我个人身上,通常有一些更好的解决方法来解决这类问题。
    猜你喜欢
    • 1970-01-01
    • 2017-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-15
    • 1970-01-01
    相关资源
    最近更新 更多