【问题标题】:What are the "serious performance implications" of implicit_flush?隐式刷新的“严重性能影响”是什么?
【发布时间】:2014-07-14 08:02:39
【问题描述】:

我网站的管理部分有一堆非常慢的报告生成脚本echo 在生成时逐行输出。为了让这个输出立即刷新到浏览器,而不是让用户在看到任何响应之前等待几分钟,我们禁用了output_buffering,并在此类脚本的开头调用ob_implicit_flush

为方便起见,我正在考虑只打开 php.ini 中的 implicit_flush 设置,而不是向每个将从中受益的脚本添加 ob_implicit_flush() 调用。

但是,文档包含以下可怕但无法解释的评论:

implicit_flush

...

在 Web 环境中使用 PHP 时,打开此选项会严重影响性能,通常建议仅用于调试目的。

这些“严重的性能影响”是什么?它们是否证明手册的建议是合理的?

【问题讨论】:

  • 虽然我已经用我能够发现的 一个 答案自行回答了这个问题,但我仍然有兴趣了解是否还有其他答案。我在回答中描述的性能陷阱很可能实际上不是手册所暗示的。

标签: php configuration output-buffering php-ini


【解决方案1】:

这可能是手册所暗示的内容,也可能不是,但是打开implicit_flush 或调用ob_implicit_flush() 对性能有严重影响的一种情况是,通过mod_phpmod_deflate 将PHP 与Apache 一起使用已启用。

在这种情况下,flush() 调用能够将输出一直通过mod_deflate 推送到浏览器。如果您有任何脚本以小块回显大量数据,则刷新每个块将削弱 mod_deflate 压缩输出的能力,很可能导致“压缩”形式大于原始内容。

作为一个极端的例子,考虑这个回显一百万个随机数的简单脚本:

<?php
    header('Content-Type: text/plain');

    for ($i=0; $i < 1000000; $i++) { 
        echo rand();
        echo "\n";
    }
?>

output_buffering 关闭,implicit_flush 也关闭(暂时),让我们在 Chrome 中打开开发工具:

注意大小/内容列;解压后的输出大小为 10.0MB,但由于 mod_deflate 的 gzip 压缩,整个响应被压缩到 4.8MB,大小大约减半。

现在在implicit_flush 设置为On 的情况下使用完全相同的脚本:

再一次,“解压缩”输出大小为 10.0MB。不过这一次,HTTP 响应的大小是 28.6MB - mod_deflate 的“压缩”实际上是响应大小的三倍。

对我来说,这足以让我听从 PHP 手册的建议,即离开 implicit_flush 配置选项关闭,并且只使用 ob_implicit_flush()(或手动 flush() 调用)在这样做实际上有目的的情况下。

【讨论】:

  • 你知道 TCP 层发生了什么吗?对于后一种情况,可能有多个重组的 TCP 数据包?
  • @Gumbo 不知道;恐怕这比我在专业上需要了解或思考的更接近金属。不过,既然你已经问过了,我会试着找出答案。
猜你喜欢
  • 2015-07-25
  • 1970-01-01
  • 2015-12-03
  • 1970-01-01
  • 2010-09-22
  • 1970-01-01
  • 2011-01-20
  • 1970-01-01
  • 2020-07-23
相关资源
最近更新 更多