如何在 IIS 6 上配置 FastCGI 以正确加载 Perl 模块
我已经取得了一些部分的成功,但无法跨过最后的坎。
症状:在测试模式下 FastCGI 运行良好。当在 eval 或 do 模式下运行普通 Perl 脚本时,它的性能非常好。一旦我尝试访问 FCGI::Request() 对象或 CGI::Fast->new 对象,它就会无限期挂起。这是我的配置:
[Types]
fcgi=FCGI
cgi=FCGI
pl=FCGI
pm=FCGI
[FCGI]
ExePath=C:\perl\bin\perl.exe
;ExePath=C:\strawberry\perl\bin\perl.exe
Arguments="-MFCGI::IIS=eval"
;Arguments=d:\inetpub\cgi-bin\hello.fcgi
;Arguments=d:\inetpub\cgi-bin\h2.fcgi
ActivityTimeout=5
QueueLength=999
MaxInstances=20
InstanceMaxRequests=500
您可以看到我在上面用 ; 引用过的内容。使用 ActiveState 或 Strawberry 会导致相同的行为。如果我将 -MFCGI::IIS 参数设置为“test”,它将完美运行测试。 Eval、do 和 no 设置都无限期挂起。
最明显的是,如果我将 Arguments = 设置为有效的 FCGI 文件(或 .pl/.cgi/.pm),那么该单个脚本将完美运行。 Perl 实例在调用中精确地保持其应有的状态,并且以宣传的速度运行。对 FCGI::Request() 或 CGI::Fast->new 方法的调用都会返回它们应该返回的对象。一切都非常美好,但这不是正确的配置。我有大量的 cgi 文件,我必须为每个 cgi 文件创建一个单独的映射条目才能使这个丑陋的拼凑工作发挥作用。
我怀疑我缺少一个设置,导致脚本名称作为参数发送给 perl,但我看不到参数。感谢您的任何帮助。
编辑:我的怀疑是不正确的。 FCGI 肯定调用了正确的脚本,但不知何故它在错误的环境中调用了它们。如果我使用 -MFCGI::IIS 参数,我将调用与使用显式路径参数完全相同的脚本,但是当我使用显式路径参数时,脚本可以找到它们的库。我的挑战是让脚本正确识别它们的库。
当使用 -MFCGI::IIS 时,此脚本失败:
#!c:/perl/bin/perl
use CGI::Fast;
错误是:
Error!
Can't locate object method "FILENO" via package "FCGI::Stream" at
C:/Perl/lib/CGI.pm line 822.
Compilation failed in require at C:/Perl/lib/CGI/Fast.pm line 20.
BEGIN failed--compilation aborted at C:/Perl/lib/CGI/Fast.pm line 20.
Compilation failed in require at (eval 4) line 4.
BEGIN failed--compilation aborted at (eval 4) line 4.
当使用显式脚本引用时,此脚本完全成功。它维护相同的 perl PID、维护其计数并返回准确的值。但大多数情况下,它可以导入其模块。
#!c:/perl/bin/perl -w
use strict;
use CGI::Fast;
my $count = 1;
while (my $q = CGI::Fast->new)
{
print("Content-Type: text/plain\n\n");
print("Process ID: $$; Count is: " . ++$count);
}
我必须设置一些 ENV 变量才能使 perl 能够找到它的模块。
I've achieved several partial successes, but can't cross the last hurdle.
Symptom: When in test mode FastCGI performs perfectly. When running plain perl scripts in eval or do mode it performs perfectly. As soon as I attempt to access the FCGI::Request() object or the CGI::Fast->new object, it hangs indefinitely. Here's my config:
[Types]
fcgi=FCGI
cgi=FCGI
pl=FCGI
pm=FCGI
[FCGI]
ExePath=C:\perl\bin\perl.exe
;ExePath=C:\strawberry\perl\bin\perl.exe
Arguments="-MFCGI::IIS=eval"
;Arguments=d:\inetpub\cgi-bin\hello.fcgi
;Arguments=d:\inetpub\cgi-bin\h2.fcgi
ActivityTimeout=5
QueueLength=999
MaxInstances=20
InstanceMaxRequests=500
You can see the things I've tried referenced above with ;'s. Using ActiveState or Strawberry results in the same behavior. If I set the -MFCGI::IIS argument equal to "test", it runs the tests perfectly. Eval, do, and no setting all hang indefinitely.
Most tellingly, if I set the Arguments = to a valid FCGI file (or .pl/.cgi/.pm) then that single script will run perfectly. The perl instance persists across calls precisely as it should, and it runs with advertised speed. The calls to the FCGI::Request() or CGI::Fast->new methods all return the objects they should. Everything is positively hunky dory, but that's not the correct config. I have a raft of cgi files, and I'd have to create a separate mapping entry for each cgi file to make that ugly kludge work.
I suspect I'm missing a setting that causes the name of the script to be sent as an argument to perl, but I can't see the param. Thanks for any help.
Edit: My suspicion is incorrect. FCGI is definitely calling the correct scripts, but it's calling them with the wrong environment somehow. If I use the -MFCGI::IIS argument, I call exactly the same script as if I use the explicit path argument, but when I use the explicit path argument the scripts can find their libraries. My challenge is to get the scripts to identify their libraries correctly.
When using -MFCGI::IIS this script fails:
#!c:/perl/bin/perl
use CGI::Fast;
The error is:
Error!
Can't locate object method "FILENO" via package "FCGI::Stream" at
C:/Perl/lib/CGI.pm line 822.
Compilation failed in require at C:/Perl/lib/CGI/Fast.pm line 20.
BEGIN failed--compilation aborted at C:/Perl/lib/CGI/Fast.pm line 20.
Compilation failed in require at (eval 4) line 4.
BEGIN failed--compilation aborted at (eval 4) line 4.
When using an explicit script reference, this script succeeds completely. It maintains the same perl PID, maintains its count, and returns accurate values. Mostly, though, it can import its modules.
#!c:/perl/bin/perl -w
use strict;
use CGI::Fast;
my $count = 1;
while (my $q = CGI::Fast->new)
{
print("Content-Type: text/plain\n\n");
print("Process ID: $; Count is: " . ++$count);
}
There has just got to be some ENV var I can set to make perl able to find its modules.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Microsoft 报告他们的 FastCGI 工具未使用 Perl 进行测试。你无法从这里到达那里。另一方面,您可以使用 IIS 7 和 PerlEx30.dll 取得进展。在被叫去另一个项目之前,我有一些运气。
Microsoft reports their FastCGI tool is not tested with Perl. You can't get there from here. On the other hand, you can make progress using IIS 7 and PerlEx30.dll. I had some luck with that before being called to another project.