调用ob_end_flush时超时问题排查(WordPress+Nginx+PHP-FPM环境)
问题:Nginx+PHP-FPM环境下WordPress大缓冲输出超时瓶颈排查
环境信息
nginx version: nginx/1.21.1 PHP 7.4.33 WordPress 6.1.1
问题描述
当通过ob_get_length()测量到缓冲数据达36MB时,WordPress内置的wp_ob_end_flush_all()函数经常在5分钟后超时,偶尔需要6-7分钟才能执行成功,该数据量对当前使用的WP插件而言属于合理范围。
函数代码如下:
function wp_ob_end_flush_all() { $levels = ob_get_level(); for ( $i = 0; $i < $levels; $i++ ) { ob_end_flush(); } }
已尝试的排查动作:
- 关闭
zlib.output_compression,问题未解决 - 替换shutdown钩子禁用缓冲,添加
X-Accel-Buffering: no头,问题仍存在:
\remove_action('shutdown', 'wp_ob_end_flush_all', 1); \add_action('shutdown', function() { header('X-Accel-Buffering: no'); $levels = \ob_get_level(); for ( $i = 0; $i < $levels; $i++ ) { \ob_end_flush(); } }, 1);
编辑补充
将max_execution_timeout调至600后,加载耗时变为6.2分钟,但36MB数据压缩后仅902KB,怀疑PHP-FPM与Nginx之间的通信存在异常。
可能的瓶颈方向
- PHP-FPM缓冲区与内存配置:检查
php.ini中的memory_limit、output_buffering,以及php-fpm.conf里的request_terminate_timeout、pm.max_requests等参数。即使压缩后数据量小,PHP在flush大缓冲区时,若内存分配不足或缓冲区分段过小,会导致逐段传输效率极低。 - Nginx FastCGI缓冲区设置:调整Nginx的
fastcgi_buffer_size和fastcgi_buffers参数,确保缓冲区能容纳足够的未压缩数据(比如设置为fastcgi_buffers 8 64k;或更大)。如果缓冲区过小,Nginx会频繁将数据写入临时文件,磁盘IO的延迟会拖慢整个传输流程。 - 套接字/网络传输限制:若PHP-FPM与Nginx使用Unix套接字,检查
listen.backlog参数是否足够,以及套接字文件的权限是否正确;若使用TCP连接,检查内核的net.core.somaxconn等参数是否限制了连接队列长度,导致数据传输阻塞。 - WordPress插件的额外处理:部分插件可能会在输出缓冲中执行字符串替换、内容过滤等操作,36MB的原始数据做这类操作会占用大量CPU时间,导致flush前的处理耗时过长。可以临时禁用所有插件测试,再逐个排查定位问题插件。
- Nginx压缩配置影响:虽然PHP端关闭了压缩,但如果Nginx开启了
gzip压缩,在接收PHP的原始数据后会自行压缩。若服务器CPU资源不足,或gzip_comp_level设置过高,压缩过程会消耗大量时间,导致整体响应延迟。可以临时关闭Nginx的gzip功能验证。 - 内核资源限制:检查Linux系统的
fs.file-max(文件句柄上限)、vm.swappiness(内存交换策略)等参数,若系统因资源不足导致进程阻塞,也会出现超时或缓慢的情况。
内容的提问来源于stack exchange,提问作者user2867106
相关产品推荐
相关产品推荐

