首页 > 解决方案 > 从 php-mod 切换到 php-fpm 输出缓冲问题

问题描述

当使用 php-mod 和 fastcgi 时,代码执行得很好,每一秒我都会得到一个输出,但是切换到 php-fpm 代码会在输出前延迟几秒钟,具体取决于输出大小

尝试在 php ini ob_implicit_flush ob_start ob_end_flush header Content-Encoding = none implicit_flush 1 ob_end_clean 中设置输出缓冲区0的以下组合

<?php
  header('Content-Type: text/event-stream');
  header('Cache-Control: no-cache');
  while( true ){
    $time = date('r');
    echo "retry:1000\r\n";
    echo "data: ".$time;
    echo "\r\n\r\n";                    
    ob_flush();
    flush();
    sleep(1);
   }
  ?>

这适用于生产服务器,而 php-mod 不是一个选项,我也让它在带有 FcgidOutputBufferSize 0 的 Fastcgi 中工作有没有办法让代码在 php-fpm 上工作,所以输出会像在 php-mod 中一样立即发送,并且快速cgi?

PS 运行:Ubuntu 18.04、Apache 2.4.29、PHP 7.2

标签: php

解决方案


几天后,我发现让它在 php-fpm 中工作的唯一方法是填充输出缓冲区。这真是低效!让我解释 :

假设您正在使用服务器发送事件并且您的输出缓冲区是 4096,即使您没有返回任何内容,您仍然每秒处理一次,您仍然向客户端发送大约 4Kb 的输出,其中 mod_php 和 fast-cgi 仅在有输出时发送数据。

如果其他人有这个问题,这是我最好的解决方案:在 php-fpm ex 上运行主站点。example.com 并创建一个子域 ex。push.example.com 并在子域上设置 fast-cgi / php_mod[NOT RECOMMENDED PRODUCTION] 现在您可以保持连接打开并处理数据,而无需向客户端发送输出。

PS。我将会话变量保存在数据库中,因此域和子域都可以访问它,请参见https://github.com/dominicklee/PHP-MySQL-Sessions另一件事是让子域发送 CORS。在 PHP 中添加 header('Access-Control-Allow-Origin: https://example.com ');


推荐阅读