如何提高非持久 CGI 进程中的 Moose 性能?
Moose 是一个非常棒的对象框架。问题在于,连同它的依赖项一起,它非常大。我们的分析表明,在我们的平台上,仅加载 Moose 就会在非持久性 CGI 应用程序脚本上产生 5-6 秒的开销。对于这些一次性应用程序来说,这是不可接受的。
相比之下,当我们使用持久进程系统(例如 FCGI)时,这种启动开销就被消除了(或者更确切地说,只发生一次),一切都很好。我们面临的问题是,我们无法保证所有代码始终在持久进程下运行。
我们研究了使用 鼠标 作为 Moose 的功能有限的直接替代品,但作为事实证明(如这个答案)这不是一个可行的选择。我们编写的与 Moose 一起使用的任何库都无法以微妙但重要的方式与 Mouse 一起使用。而且我们真的不想分叉我们的所有模块,这样我们就可以在持久环境中支持 Moose,并在“普通”CGI 中支持 Mouse。
鉴于此,我们有以下选择:
- 分叉我们的内部模块,以根据需要与 Moose 或 Mouse 配合使用。 (糟糕!)
- 只为 FCGI/Moose 开发我们的模块。不再支持“普通”CGI。如果我们必须编写非持久性的脚本,他们将无法利用我们的内部模块。
- 不要使用 Moose 或 Mouse,而是使用其他一些对象框架。
哪个选项最好?我们现在倾向于 2,如果我们必须让某些东西作为普通 CGI 运行,我们就会接受它。其他框架怎么样?我们应该考虑一些更轻量级的东西吗?
Moose is a fantastic object framework. The trouble is that, taken together with its dependencies, it's very big. Our profiling indicates that on our platform, simply loading Moose will incur a 5-6 second overhead on non-persistent CGI application scripts. That's just not acceptable for these one-off applications.
By contrast, when we're using a persistent process system (such as FCGI), this startup overhead is eliminated (or rather, only incurred once), and all is well. The problem we have is that we can't guarantee that all of our code will always run under a persistent process.
We investigated using Mouse as a feature-limited drop-in-replacement for Moose, but as it turns out (as mentioned in this answer) that's not a viable option. Any libraries we write to work with Moose will fail to work with Mouse in subtle but important ways. And we really don't want to fork all of our modules so that we can support both Moose in a persistent environment and Mouse for "vanilla" CGI.
Given that, we have the following options:
- Fork our in-house modules to work with either Moose or Mouse, as appropriate. (Yuck!)
- Only develop our modules for FCGI/Moose. Don't support "vanilla" CGI anymore. If we have to write scripts that aren't persistent, they won't be able to leverage our in-house modules.
- Don't use either Moose or Mouse, but some other object framework.
Which option is best? We are leaning towards 2 right now, and we'll just suck it up if we have to get something running as a vanilla CGI. How about other frameworks? Is there anything more lightweight we should be looking at?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我的偏好是放弃普通 CGI 支持。如今 FCGI 托管确实很便宜,没有理由迎合普通的 CGI (IMO),因为它只会强化 Perl 速度慢的观点。但如果你无法避免它,那么你可以使用类似 Object::Tiny。但如果您需要角色、约束、元编程以及 Moose 提供的所有其他可爱功能,那么除非您放弃普通的 CGI,否则您就不走运了。
My preference would be to drop vanilla CGI support. FCGI hosting is really cheap these days and there's no reason to pander to vanilla CGI (IMO) because it just reinforces the opinion that Perl is slow. But if you can't avoid it then you can use something like Object::Tiny. But if you need Roles, constraints, meta-programming and all the other loveliness that Moose provides, you're out of luck unless you drop vanilla CGI.
您可以使用 Moose 编写后端服务器应用程序,然后编写非常小、简单的 CGI 脚本来查询后端。
这或多或少就是 FCGI 所做的,因此仅使用 FCGI 可能更有意义。
另一方面,拥有一个可以根据需要连接任何抽象接口的非 cgi 后端服务器可能会带来真正的好处。
例如,如果您使用 TCP(或 UDP)套接字,那么您可以让本机桌面应用程序访问与 CGI 相同的后端。
最适合您的情况实际上取决于您的具体情况。根据情况的详细情况,我可以看到自己决定使用这种方法或您上面概述的任何方法。
You could write a back end server application using Moose, and then write very small, simple CGI scripts that query the back end.
This is more-or-less what FCGI does, so it may make more sense to just use FCGI.
On the other hand, there may be real benefits in having a non-cgi back end server that can have ANY abstract interface bolted on as needed.
For example, if you use TCP (or UDP) sockets, then you could have a native desktop application hit the same back end as your CGI.
What the best fit is in your case really depends on your specific situation. Depending on the details of the situation, I can see myself deciding to use this approach or any of the approaches you outline above.
我的建议是采用选项#2,然后帮助我们重构 Moose,以便 CGI 变得可行。 fREW 目前正在开发 Moose 测试套件,以便启用 MooseX::Antlers 项目,该项目应该会减少大部分开销,这意味着 Moose 无法用于 CGI 环境。
目前 MooseX::Antlers 背后的人 Matt Trout (mst) 表示希望能够在必要时在 CGI 环境中运行应用程序。我建议现在继续使用 FCGI,并缠着他寻求帮助!
My suggestion is to go with option #2 and then help us refactor Moose so that CGI becomes viable. fREW is currently working on the Moose test suite in order to enable the MooseX::Antlers project which should reduce most of the overhead that means Moose is unusable for a CGI environment.
Matt Trout (mst), the man currently behind MooseX::Antlers, has expressed a desire to be able to run apps in a CGI environment if neccessary. I'd suggest stick with FCGI for now and pester him for what you can do to help out!
Jonathan Rockway 写了一篇关于 APP::Peristent 的文章(奇怪的是,它不是t in CPAN) 几个月前。我还没有使用过它,但根据他上面链接的博客文章,它看起来提供了一个相当透明的服务器-客户端架构,您可以将 CGI 的实际处理包装在其中。
Jonathan Rockway wrote about APP::Peristent (which, oddly, isn't in CPAN) a few months ago. I haven't used it, but based on his above-linked blog post, it looks to provide a fairly transparent server-client architecture that you could wrap the actual processing of your CGI in.
App::Persistent
、pperl
、SpeedyCGI
以及其他一些可能是,将 Perl 程序编译为字节代码的过程只完成一次,并且某种之后的调用将使用缓存。由于 Moose 据说有相当大的编译时惩罚,我会首先尝试这种方法。我已经成功地使用
pperl
在古代绘制了许多 MRTG 图系统大约在 2001 年。 Perl 程序针对每个图形执行,这是相当大的开销——这可能与您的 CGI 场景相当。The basic idea of
App::Persistent
,pperl
,SpeedyCGI
and probably some others is that the process of compiling your Perl program to byte code is only done once and some sort of caching is used on invocations after that. Since Moose is said to have quite a compile-time penalty, I'd try this approach first.I have successfully used
pperl
for drawing lots of MRTG graphs on an ancient system around 2001. The Perl program was executed for every graph which was quite an overhead -- this probably comparable to your CGI scenario.还有另一个选项 - PPerl。
我从未使用过它,但它看起来确实很有趣。以及编写它的人(Matt Sergeant aka baud)-它实际上为您提供了高质量代码的保证。
There is also another option - PPerl.
I have never used it, but it definitely looks interesting. And the person who wrote it (Matt Sergeant aka baud) - it gives you practically guarantee of good quality code.