如何让PHP的flush()函数在Azure Web Apps环境中正常生效?
Azure Web Apps PHP运行环境异常问题解决方案
1. 循环600次运行5分钟报502/504错误
问题原因
Azure Web Apps 前端网关默认的请求超时上限为230秒(约3分50秒),600次循环总运行时长约10分钟,超出了网关的默认超时阈值。即使PHP代码中设置了max_execution_time = 0,也只能绕过PHP层面的执行时间限制,无法修改网关层面的超时规则。
解决方法
- 调整网关请求超时配置:进入Azure门户对应Web App资源页,依次打开配置 -> 常规设置,找到「请求超时(秒)」配置项,最大可设置为1800秒(30分钟),此处设置为700秒即可满足10分钟的运行需求。
- 确认PHP执行时间限制生效:部分环境下
ini_set函数会被禁用,可通过自定义php.ini的方式配置:- 在Web App的配置 -> 应用程序设置中,添加配置项
PHP_INI_SCAN_DIR,值为/usr/local/etc/php/conf.d:/home/site/ini - 进入站点的/home/site/ini目录,新建自定义php.ini文件,添加
max_execution_time = 0,重启应用后生效
- 在Web App的配置 -> 应用程序设置中,添加配置项
- 对于运行时长超过10分钟的任务,建议改用Web Jobs异步触发,避免依赖HTTP长连接。
2. 脚本输出无法实时刷新,仅在执行结束后统一展示
问题原因
Azure Web Apps 的PHP运行环境采用反向代理 + FastCGI的架构,存在PHP运行时、Web服务器、前端网关三层输出缓冲,默认的ob_flush()和flush()只能刷新PHP层面的缓冲区,无法触发上层缓冲的刷新。同时默认的网关缓冲区大小约为4KB,单条输出内容过小时会被缓存直到缓冲区填满才会发送给客户端。
解决方法
- 关闭PHP层面的输出缓冲:在之前的自定义php.ini中添加以下配置:
output_buffering = Off zlib.output_compression = Off
- 关闭Web服务器层面的输出缓冲:如果使用Apache作为运行服务器,在站点根目录新建
.htaccess文件,添加如下配置:
<IfModule mod_fcgid.c> FcgidOutputBufferSize 0 </IfModule> <IfModule mod_proxy_fcgi.c> ProxyFCGIBufferSize 0 </IfModule>
- 关闭Web Apps的压缩功能:进入Web App资源页的配置 -> 性能推荐,关闭动态压缩和静态压缩功能,避免压缩逻辑强制缓存输出内容。
- 调整代码逻辑,每次输出后添加足够的填充内容触发网关缓冲刷新,修改后的代码如下:
<?php ini_set('max_execution_time', 0); // 预先输出4KB空白填充,触发首次缓冲刷新 echo str_repeat(' ', 4096) . "<br>"; ob_flush(); flush(); for($i=0;$i<600;$i++) { echo 'printing...'.$i."<br>"; // 每次输出追加1KB空白,确保总输出超过网关缓冲区阈值 echo str_repeat(' ', 1024); ob_flush(); flush(); sleep(1); } ?>
内容的提问来源于stack exchange,提问作者Ronaldo Radunz
相关产品推荐
相关产品推荐

