当我在 Apache 下运行 cgi 脚本时,任何输出都会迅速发送到客户端。但是,当我在 nginx 下使用 fcgiwrap 运行它时,似乎没有任何东西发送到客户端,直到脚本完成或产生大量输出。特别是在使用 git-http-backend 时,这会导致克隆大型存储库时网关超时(克隆较小存储库时缺少进度信息)。
通过以下脚本可以看到这种行为。
#!/bin/bash
echo "Content-type: text/html"
echo
while :
do
echo this is a test.
sleep 5
done
在 apache 下客户端每 5 秒就会获取一些数据。
在使用 fcgiwrap 的 nginx 下,我没有得到任何数据并且网关超时。
nginx 和 fcgiwrap 是 Debian Jessie 的软件包。版本 1.1.0-5 和 1.6.2-5+deb8u4
所以问题
- 有谁知道哪个因素导致了这种行为?nginx 本身?fcgiwrap?还是两者?
- 这是可以通过配置来解决的问题吗?
- 如果是 fcgiwrap 问题,是否有可用的替代 cgi 包装器而不会出现此问题?
答案1
好的,搞清楚了。看来 nginx 和 fcgiwrap 都存在不受欢迎的缓冲。对于 nginx,似乎可以通过配置禁用它,而 fcgiwrap 则需要补丁。
我已经在以下位置发布了 fcgiwrap 的 debdiffhttp://bugs.debian.org/cgi-bin/bugreport.cgi?bug=863478这添加了一个新选项 NO_BUFFERING
(更新:Debian 现在已经应用了该补丁,因此如果您正在运行 Debian Buster 或更高版本,则无需自行应用它)。
然后需要更改 nginx 配置以将 NO_BUFFERING 选项传递给 fcgiwrap 并禁用 nginx 内部缓冲。
为此,我在“include fastcgi_params;”行之前和之后添加了一些设置。
#note: NO_BUFFERING relies on a patched fcgiwrap.
fastcgi_param NO_BUFFERING 1;
include fastcgi_params;
gzip off;
fastcgi_buffering off;