通过 mod_proxy 禁用 Apache 和 PHP-FPM 的输出缓冲区

Env*_*rex 5 php apache

将 Apache 与 PHP 作为模块一起使用时,PHP 生成后立即输出内容是可以的,因为您可以简单地禁用 PHP 中的 output_buffering 并使用 flush() 或 implicit_flush(1)。这是我以前用过的,效果很好。

自从切换到 PHP-FPM 以来,我遇到了一个问题,其中在整个脚本完成之前我无法让 Apache (2.4) 输出 PHP 的内容。我仍然关闭了 output_buffering 并刷新到位,但这还不够。Apache 没有使用 mod_gzip(无论如何这也会影响 PHP 模块)。

Nginx 有一个禁用 proxy_buffering 的选项,通过阅读其他人的评论可以解决这个问题,但我在 Apache 中找不到任何方法。

以下是当前在 Apache 中调用 PHP 的方式:

<FilesMatch \.php$>
    SetHandler "proxy:unix:/run/php-fpm/php-fpm.sock|fcgi://localhost/"
</FilesMatch>

<Proxy fcgi://localhost/ enablereuse=on retry=0 timeout=7200 max=500 flushpackets=on>
</Proxy>
Run Code Online (Sandbox Code Playgroud)

Apache 文档提到了flushpackets(上面使用的),这似乎是所需要的,但随后又说它目前仅适用于AJS,并非所有代理内容,因此在这种情况下它不会做任何事情。

回显足够的空白来填充缓冲区可能会起作用,但这是一种非常不理想的混乱解决方法。

简而言之:有没有人知道让 Apache 尽快发送 PHP 内容的正确方法,而不是等到脚本完成?

小智 16

我通过重写您的Proxy部分成功禁用了输出缓冲(基于此答案):

<FilesMatch \.php$>
    SetHandler "proxy:unix:/run/php-fpm/php-fpm.sock|fcgi://localhost"
</FilesMatch>

<Proxy fcgi://localhost>
    ProxySet enablereuse=on flushpackets=on
</Proxy>
Run Code Online (Sandbox Code Playgroud)


gee*_*guy 5

重新发布我刚刚发布的一个非常类似问题的答案:How to disable buffering with apache2 and mod_proxy_fcgi?

一些注释,因为我刚刚花了过去几个小时尝试寻找这个问题的答案:

  1. 使用/时不可能完全禁用输出缓冲,但是您仍然可以以块的形式传输响应。mod_proxymod_proxy_fcgi
  2. 根据我的实验,在输出刷新到浏览器之前,块必须至少为 4096 字节。
  3. 可以mod_fastcgi使用或模块禁用输出缓冲mod_fcgi,但这些 mods 在 Apache 2.4 中并不那么流行/广泛使用。
  4. 如果您已mod_deflate启用但未设置SetEnv no-gzip 1虚拟主机/目录/等。这是流数据,那么 gzip 将不允许刷新缓冲区,直到请求完成。

我正在测试一些东西,看看如何最好地使用 Drupal 8 的新 BigPipe 功能将请求流式传输到客户端,并且我在此 GitHub 问题中发布了更多注释。