我们有许多(隔离的)PSGI应用程序安装,它们在同一台计算机上运行,因此要求其PSGI服务器在唯一的端口上运行。 从资源/管理的角度来看,这不太理想,但它也需要TCP/IP的(尚未测量且可能微不足道的)"开销",而Unix域套接字在同一台机器上运行时似乎是更明显的选择。
幸运的是,该应用程序在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),有没有办法通过Unix域套接字将Apache连接代理到PSGI应用程序?
Unix域套接字应该适用于自Apache 2.4.7和Starman以来的mod_proxy。
另一种方法是在单个进程中运行不同的 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',
);
};
我遇到的唯一问题是某些应用程序使用具有相同名称的不同版本的本地模块。修复后一切正常。
此方法的一个相当大的好处是,您可以在所有应用之间共享辅助角色,从而减少内存使用量(或使您能够添加更多辅助角色)。
有mod_proxy_fdpass允许Apache代理到域套接字,尽管我还没有尝试过。
我个人建议使用标准的每个应用程序端口安排,除非您可以衡量开销是否值得做一些非常规的事情。
还可以选择为每个应用使用一个专用到服务器的 IP 地址,并让它们都在其专用 IP 上的端口 80 上运行。