Plack::Builder允许挂载多个主机,例如以下代码片段:
my @sites = load_site_names();
my $apps;
for my $site (@sites) {
$apps->{$site} = Some::PsgiFramework::MyApp->new( config => get_config($site) );
}
use Plack::Builder;
builder {
for my $site (@sites) {
mount "$site" => $apps->{$site};
}
mount '/' => sub { ... };
}
e.g。
load_site_names
会返回http://example.com
,http://some.other.site.com
,...等网站的列表。Some::PsgiFramework::MyApp
我完全需要上述内容 - 需要开发一个简单的网络应用程序,该应用程序应该部署在不同(低流量)站点的数据库中,并且不希望为每个站点设置不同的PSGI服务器。
然而,Plack的作者自己说(在Plack::Request)
请注意,此模块旨在供Plack中间件使用 开发人员和Web应用程序框架开发者而不是 应用程序开发人员(最终用户)。
使用Plack :: Request直接编写Web应用程序 当然可能但不推荐:就像这样做 mod_perl的Apache :: Request:但是级别太低了。
如果您正在编写Web应用程序,而不是框架,那么您就是 鼓励使用其中一个支持的Web应用程序框架 PSGI(http://plackperl.org/#frameworks),或者查看类似的模块 HTTP :: Engine在顶部提供更高级别的请求和响应API PSGI。
这就是问题所在。
我在MetaCPAN中检查了许多不同的基于PSGI的框架。 AFAIK 每个都是基于单身的,例如不允许为同一app.psgi
中的不同站点多次共享(挂载)的写入应用程序。
所以问题是:
app.psgi
? (老实说,我没有检查催化剂 - 因为它太重了)答案 0 :(得分:0)
Plack :: App :: URLMap有一个名为Plack::App::HostMap的替代方法,它可以更快地执行查找,因为它在内部使用哈希,而不是数组。所以没有迭代进行。它只是进行哈希查找,而且它们在Perl中非常快。
权衡是现在你只能使用常量主机名。所以,如果你的列表是这样的:
example.org
example.com
example.de
example.am
example.cx
或者使用以下子域:
one.example.org
two.example.org
three.example.org
four.example.org
five.example.org
six.example.org
然后这是完美的。另一方面,我不确定它是否支持也具有常量路径部分的URL,例如http://foo.example.org/bar
,其中有很多foo
个,但它们共享相同的/bar
安装应用程序的路径。该模块根本没有任何测试,我无法尝试。如果您查看更改,至少有一个人建议使用其他功能,因此作者以外的其他人正在使用它。
要使用它,您可以从Plack :: Builder切换到使用Plack :: App :: HostMap作为您调用方法的应用程序。
use Plack::App::HostMap;
# set up %apps (e.g. foo.example.org, bar.example.org)
my $host_map = Plack::App::HostMap->new;
for my $site (@sites) {
$host_map->map( $site => $apps->{$site} );
}
你没有告诉我们/
路线应该做什么,但基本上它也需要一个主机。如果您的服务器有很多主机名,那么所有主机名都会响应此请求。这就是你想要做的全部想法。但/
的主机名是什么?因此,最好的办法是为sub { ... }
斜杠应用程序添加一行 real 主机名。也许这是一个控制面板或什么的。所以把它连接到实际的URL。
$host_map->map( "example.org" => sub { ... } );
单身人士在这里不是问题。似乎不可能让Dancer2加载不同的配置或环境。我没有尝试使用Mojo,Web :: Simple或Catalyst这个用例。
我确实尝试了很多D2,而我最接近的是在MyApp中使用/
路由,以及这个PSGI应用。请注意,不起作用。
use Plack::Builder;
my $builder = Plack::Builder->new;
foreach my $name (qw/development production/) {
$builder->mount(
"/$name" => builder {
eval <<"APP";
package MyApp::$name {
use Dancer2;
use MyApp with => { environment => "$name" };
}
APP
"MyApp::$name"->to_app;
}
);
}
$builder->to_app;
它使用由dancer2 -a MyApp
生成的默认框架和未更改的环境文件。 Plack的调度工作正常,但是Dancer2感到困惑。
HTTP::Server::PSGI: Accepting connections at http://0:5000/
[MyApp::production:4896] core @2017-02-10 02:14:42> looking for get / in /home/julien/perl5/perlbrew/perls/perl-5.20.1/lib/site_perl/5.20.1/Dancer2/Core/App.pm l. 35
[MyApp::production:4896] core @2017-02-10 02:14:42> Entering hook core.error.init in (eval 49) l. 1
[MyApp::production:4896] core @2017-02-10 02:14:42> Entering hook core.error.before in (eval 49) l. 1
[MyApp::production:4896] core @2017-02-10 02:14:42> Entering hook core.error.after in (eval 49) l. 1
127.0.0.1 - - [10/Feb/2017:02:14:42 +0100] "GET /production/ HTTP/1.1" 404 456 "-" "curl/7.47.0"
[MyApp::development:4896] core @2017-02-10 02:18:06> looking for get in /home/julien/perl5/perlbrew/perls/perl-5.20.1/lib/site_perl/5.20.1/Dancer2/Core/App.pm l. 35
[MyApp::development:4896] core @2017-02-10 02:18:06> Entering hook core.error.init in (eval 49) l. 1
[MyApp::development:4896] core @2017-02-10 02:18:06> Entering hook core.error.before in (eval 49) l. 1
[MyApp::development:4896] core @2017-02-10 02:18:06> Entering hook core.error.after in (eval 49) l. 1
127.0.0.1 - - [10/Feb/2017:02:18:06 +0100] "GET /development HTTP/1.1" 404 457 "-" "curl/7.47.0"
我的想法是使用相同的包文件并将其子类化以通过with
获取不同的配置。
但是,可以一遍又一遍地在循环中定义相同的应用程序。您可以移动路径处理程序,使用get '/' => \&main::get_slash
之类的代码引用,其中sub get_slash
不在eval
中。
use Plack::Builder;
my $builder = Plack::Builder->new;
foreach my $name (qw/development production/) {
$builder->mount(
"/$name" => builder {
eval <<"APP";
package MyApp::$name {
use Dancer2;
use Data::Printer;
set environment => "$name";
get "/" => sub { np(config) }
}
APP
"MyApp::$name"->to_app;
}
);
}
$builder->to_app;
字符串eval
并不像它在这里看到的那样邪恶,因为该代码仅在启动时运行。 D2将在内部跟踪您在此处以编程方式创建的所有应用程序。但我不知道这是多么高效。
答案 1 :(得分:0)
我认为引用的文档更适用于Plack :: Request而不是Plack :: Builder。
使用Plack :: Builder安装各种应用程序(例如Dancer / Catalyst / Mojolicious / homegrown app)是完全可以接受的,这确实非常普遍。