file_get_contents https的1分钟超时?

时间:2015-12-17 09:27:22

标签: php apache file-get-contents

当通过https访问某些资源时,我的PHP file_get_contents挂了60秒有困难。

我不确定这是客户端还是服务器端问题。

在客户端

使用命令行:

$ URL="https://example.com/some/path"
$ wget "$URL" -O /dev/null -q # takes a few milliseconds
$ curl "$URL" >/dev/null      # takes a few milliseconds
$ php -r 'file_get_contents("'"$URL"'")' # takes 61s!

在服务器上

将一行写入Apache(2.4)访问日志,以获取正确的SSL vhost 立即,并返回200(成功)响应。这令人困惑的时间表令人困惑:

  • 0s php在客户端触发的file_get_contents
  • 0.2s服务器的apache访问日志记录成功(200)。
  • ???谁知道这里发生了什么?
  • 60.2s客户端收到该文件。

从Ubuntu 14.04和Debian 8客户端测试。有问题的资源都在运行带有ITK worker和PHP 5.6的Apache 2.4的Debian 8服务器上。我已经尝试了防火墙关闭(默认的ACCEPT策略),所以不是这样。铌。服务器已禁用IPv6,这可能是相关的,因为当我首先尝试IPv6时,我注意到这样的超时。但是被访问的主机没有AAAA记录,apache日志显示(a)SSL已建立好,(b)请求有效并已收到。

3 个答案:

答案 0 :(得分:1)

一个可能的答案:您确定客户端仅在60.2秒后收到文件吗?如果我没记错的话,file_get_contents()有一个讨厌的习惯,就是在它认为请求完成之前等待远程连接关闭。这意味着,如果您的服务器使用HTTP保持活动状态,一旦所有数据传输完成,这将有效地保持连接一段时间,您的应用程序可能会挂起。

这样的事情有帮助吗?

$context = stream_context_create(['http' => ['header' => 'Connection: close\r\n']]);
file_get_contents("https://example.com/some/path", false, $context);

注意:您可能需要使用' https'对于该阵列中的键;我不记得我的头脑。

答案 1 :(得分:1)

尝试跟踪脚本 php -r 'file_get_contents("'"$URL"'")' &将在后台运行脚本并显示脚本pid。而不是strace -p %pid%

答案 2 :(得分:1)

感谢你给我更深刻的答案!

这似乎是使用 ITK Apache MPM工作者的错误/怪癖。

  • 使用该模块时,此问题(file_get_contents未关闭连接)显示出来。

  • 如果没有这个模块,问题就会消失。

自从升级到Debian Jessie / Apache 2.4以来,这不是我在该模块中发现的第一个错误。我会尝试举报。

啊哈哈!我是正确的。它是a bug并且已经发布了修补程序,目前正在Debian jessie中提出更新。