访问“/”时,Apache 会因 FallbackResource 挂起五秒钟

访问“/”时,Apache 会因 FallbackResource 挂起五秒钟

我正在运行 Apache 2.4.6(Amazon)和 PHP 5.4.21 的标准安装,并使用以下配置作为我的虚拟主机:

DirectoryIndex index.php
# ...
FallbackResource /index.php

我的index.php是简单的缩影:

<?php echo "Hello world";

访问时http://<server-name>/,五秒钟后才显示完整页面,这太神奇了!其他页面的响应时间都符合预期(很快)。

我发现,这五秒钟与该Keep-Alive功能的默认等待时间有关;在这种情况下,直到 Apache 在等待时间之后切断连接,才会发送分块响应的最后几个字节。顺便说一句,这也完全破坏了持久连接本来可以给你带来的所有好处。

这是 Apache 的一个已知错误吗?还是我忽略了某些非常明显的东西?

答案1

2017/04/18:此问题已在 Apache 2.4.25 中修复:https://bz.apache.org/bugzilla/show_bug.cgi?id=58292

来自错误摘要的解释:

如果在子请求上执行 FallBackResource,服务器将永远不会发送最后一块,从而导致某些客户端出现挂起。

发生这种情况的原因是 EOS 存储桶被子请求过滤器剥离,如果多个子请求过滤器最终出现在一个列表中,则无法正确删除该存储桶

这种行为仅在应用压缩时才会显现,因为这依赖于知道流何时结束;并且 5s 是使用的默认套接字超时。

旧答案

此错误报告我意识到这个问题可能与该DirectoryIndex指令有关。

标准 Apache 安装的配置中包含以下部分:

<IfModule dir_module>
DirectoryIndex index.html
</IfModule>

此语句之后的任何指令(例如虚拟主机中的指令)都不会覆盖此设置;相反,它会被添加到请求索引时将尝试的页面堆栈中。在读取请求后立即执行strace httpd -X并检查调用时,可以确认此行为,例如:stat()

stat("/path/to/vhost/index.html", 0x7fff9dc41b90) = -1 ENOENT
stat("/path/to/vhost/index.php", {st_mode=S_IFREG|0664, st_size=130, ...}) = 0

虽然我不能确切地说出原因,但DirectoryIndex在指定之前必须清除所有先前的指令DirectoryIndex index.php,即index.php必须是尝试处理请求的第一个页面。

可以使用以下配置来完成:

DirectoryIndex disabled
DirectoryIndex index.php

相关内容