通过Unix域套接字的Apache-to-PSGI代理

时间:2013-02-01 14:29:43

标签: perl apache proxy psgi

我们有许多(隔离的)PSGI应用程序安装在同一台机器上运行,因此需要他们的PSGI服务器在独特的端口上运行。从资源/管理的角度来看,这是不太理想的,但是当在同一台机器上运行时,Unix域套接字似乎是更明显的选择时,它还需要TCP / IP的“尚未测量且可能无关紧要”的“开销”。

幸运的是,该应用程序在Plack的HTTP接口下工作(通过mod_proxy的“ProxyPass”从Apache代理),但不幸的是,它在FastCGI接口下断开(参见:https://stackoverflow.com/questions/14643165/can-psgi-apps-fork-under-plackhandlerfcgi)。

除了mod_fastcgi的FastCgiExternalServer(或使用这个未经测试的,用户提供的补丁修补mod_proxy:http://mail-archives.apache.org/mod_mbox/httpd-dev/201207.mbox/%3C20120731200351.GB11038@gmail.com%3E),有没有办法将Apache连接通过Unix域套接字代理到PSGI应用?

2 个答案:

答案 0 :(得分:3)

自Apache 2.4.7和mod_proxy以来,代理到Unix域套接字应该与Starman一起使用。

另一种方法是在一个进程中运行不同的PSGI应用程序。我使用类似于以下包装器的东西来实现这个目的:

use strict;
use warnings;

use lib qw(
    /path/to/app1
    /path/to/app2
    /path/to/app3
);

use Plack::Builder;
use Plack::Util;

sub load_psgi_in_dir {
    my ($dir, $psgi) = @_;
    my $app = Plack::Util::load_psgi("$dir/$psgi");
    return sub {
        chdir($dir);
        return $app->(@_);
    };
}

builder {
    mount 'http://app1.com/' => load_psgi_in_dir(
        '/path/to/app1',
        'app1.psgi',
    );
    mount 'http://app2.com/' => load_psgi_in_dir(
        '/path/to/app2',
        'app2.psgi',
    );
    mount 'http://app3.com/' => load_psgi_in_dir(
        '/path/to/app3',
        'app3.psgi',
    );
};

我遇到的唯一问题是某些应用程序使用了具有相同名称的本地模块的不同版本。在确定一切正常后。

这种方法的一个显着好处是,您可以在所有应用程序之间共享工作人员,从而减少内存使用量(或者允许您添加更多工作人员)。

答案 1 :(得分:2)

mod_proxy_fdpass允许Apache代理域套接字,但我还没有尝试过。

我个人建议使用标准的每个app-on-a-port安排,除非你可以衡量开销是否值得做一些非常规的事情。

您还可以选择为每个应用程序使用一个私有到服务器的IP地址,并让它们全部在其私有IP上的端口80上运行。