1

我有一个用 编写的遗留 Perl CGI 脚本CGI.pm,它通过 CGI 界面打印一些文本行来回复其进度。然后,它的旧客户端将逐行读取响应并执行任何操作。

由于缓冲问题,我无法设置 nginx 使其工作。

我的设置:

  1. CentOS 7 + EPEL
  2. yum install fcgi fcgi-devel spawn-fcgi
  3. fcgiwrap最近需要一个补丁来支持NO_BUFFERING环境变量,以关闭缓冲。这在 ServerFault的这个答案中有所描述。然而,令人费解的是:

    1. 该答案中链接的 debian 错误报告声称该补丁已被上游应用fcgiwrap,但上游github存储库中没有任何相关内容,除了从未回复过的未解决问题。反正补丁已经应用到debian包了,但是EPEL包不包含它,所以:
    2. git clone存储库
    3. debian_patches_add-environment-variable-NO_BUFFERING-to-disable-out.patch从上面的 debian bugreport应用。
    4. autoreconf -i && ./configure && make && make install
  4. 已配置span-fcgi,这是\etc\sysconfig\spawn-fcgi

OPTIONS="-u nginx -g nginx -a 127.0.0.1 -p 9001 -P /var/run/spawn-fcgi.pid -- /usr/local/sbin/fcgiwrap -f"
  1. nginx为 fastcgi配置:
location ~ .cgi$ {
  fastcgi_pass 127.0.0.1:9001;
  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  fastcgi_request_buffering off;
  fastcgi_read_timeout 900s;
  fastcgi_param NO_BUFFERING 1;
  gzip off;

  include /etc/nginx/fastcgi_params;
}

其他信息:

  1. perl 脚本就是$| = 1;这样做的,因为脚本本身不应该缓冲自己的输出。
  2. perl 脚本还发送HTTP 标头,这通常被称为禁用 nginx 缓冲所必需的,尽管在配置文件中X-Accel-Buffering: no不应该需要它。fastcgi_buffering off
  3. 通过使用netcat( nc -l 9001 > request.txt) 监听 9001 端口,我检查了nginx是否正确传递NO_BUFFERING了请求中的变量以及所有其他参数。
  4. 通过这样做cat request.txt | nc localhost 9001,我看到fcgiwrap了缓冲输出的原因:如果我在中途终止了生成的 cgi 进程,我将获得在那之前生成的所有输出。
  5. CGI 脚本已启动并且工作正常,否则只是客户端没有逐行接收数据(但我需要fastcgi_read_timeout 900s上面的行以避免超时)。
  6. 我不确定我是否完全理解fcgiwrap源代码,但补丁很简单:如果设置了环境变量,它只会FCGI_fflush在每次写入后调用。NO_BUFFERING但是,可以肯定的是,我替换unbuffered = !!getenv("NO_BUFFERING");unbuffered = 1;,但没有成功。

那么有人能发现我错过了什么吗?

4

0 回答 0