Perl CGI :: Fast在不发送数据的情况下关闭连接

Mos*_*atz 4 perl fastcgi nginx cgi-application

我正在尝试部署一个CGI::Application通过Nginx使用的Perl应用程序,使用FastCGI在它们之间进行通信.

Nginx不断返回"502 Bad Gateway",错误日志填写如下:

2015/02/03 12:40:03 [错误] 11209#0:*2上游过早关闭连接,同时从上游读取响应头,客户端:10.1.1.23,服务器:www.example.com,请求:"GET/test .fcgi HTTP/1.1",上游:" http://127.0.0.1:5001/test.fcgi ",主持人:"www.example.com"

这是Nginx站点配置:

upstream @perl {
#   I had been trying to use a socket, but I switched to TCP to try WireShark.
#   server unix:/var/run/nginx/my-app.sock;
    server 127.0.0.1:5001;
}

server {
    listen       80;
    listen       443 ssl;

    server_name www.example.com;
    root /home/example/sites/www.example.com;

    location ~* \.fcgi(/|$) {

        fastcgi_split_path_info ^(.+?\.cgi)(/.*)$;
        # (I know that the `if` is old-style, and that `try_files` is better, but that shouldn't affect whether it works or not.)
        if (!-f $document_root$fastcgi_script_name) {
                return 404;
        }

        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Port 443;
        proxy_pass http://@perl;
    }
}
Run Code Online (Sandbox Code Playgroud)

要查看问题是否与Perl应用程序本身有关,我根据CGI::Fast文档中的测试代码创建了一个新的fcgi应用程序:

#!/usr/bin/perl -wT

use CGI::Fast;

# Added this to see if there are errors.    
# See http://perldoc.perl.org/CGI/Carp.html
BEGIN {
    use CGI::Carp qw(carpout);
    open(LOG, ">>/home/example/sites/www.example.com/err.log") or
      die("Unable to open mycgi-log: $!\n");
    carpout(LOG);
}

local $count = 0;

$ENV{FCGI_SOCKET_PATH} = "127.0.0.1:5001";
$ENV{FCGI_LISTEN_QUEUE} = 100;

while ( my $q = new CGI::Fast ) {
    $count++;
    print $q->header( "text/plain" ),
          "You are request number $count. Have a good day!\n";
}
Run Code Online (Sandbox Code Playgroud)

当我运行时./test.fcgi,我可以看到netstat它已绑定到端口5001.当我转到浏览器中的URL时,我仍然可以使用这个超级简单的应用程序获得502.错误日志中没有任何内容Carp正在写入.

我不想使用普通的CGI(通过包装脚本),因为应用程序的启动时间很长,我无法将整个应用程序转换为Plack/PSGI.

我怎么能弄清楚为什么Nginx不会与Perl交谈CGI::Fast,甚至是文档中的简单示例?

dus*_*uff 6

您正在运行FastCGI服务器,但您告诉Nginx连接到HTTP服务器.这些协议不一样.

要从Nginx连接到FastCGI服务器,请使用ngx_http_fastcgi_module,而不是ngx_http_proxy_module,例如:

fastcgi_pass 127.0.0.1:5001;
Run Code Online (Sandbox Code Playgroud)

请注意,此proxy_set_header模块不适用,因为FastCGI使用CGI环境变量,而不是标头.如果需要设置额外的标题,可以使用fastcgi_param指令来完成,例如

fastcgi_param ENVIRONMENT_VARIABLE $value;
Run Code Online (Sandbox Code Playgroud)

Nginx fastcgi_param在一个文件中附带了一些标准指令,您可能只想导入批发:

include fastcgi_params;
Run Code Online (Sandbox Code Playgroud)