buffer_output_size是单次send/end调用的数据长度上限,非总缓冲区容量或网络拥塞解决方案;超限主因是业务误用大文件直读、未压缩json等,应优先优化逻辑而非盲目调参。

直接调大 buffer_output_size 并不能根治大包发送失败问题,关键在于理解它的真实作用和触发场景——它只是单次 send 或 end 调用的数据长度上限,不是“缓冲区总容量”,也不是解决网络慢、客户端卡顿的万能开关。
buffer_output_size 是什么,不是什么
它是单次调用的硬性字节上限,比如设为 128 * 1024(128KB),那 $response->end($bigData) 中的 $bigData 长度就不能超过这个值,超了就报错:
WARNING finish (ERRNO 1203): The length of data [262144] exceeds the output buffer size[131072]
它不是:
- 客户端连接的总待发缓存(那是 socket_buffer_size 管的)
- Worker 进程的内存池大小(那是 worker_num × buffer_output_size 的理论峰值,但 v4.5+ 后已不预占内存)
- 网络拥塞时的自动分片机制(TCP 层自己分片,Swoole 不介入)
遇到溢出错误,优先检查这三类代码问题
大多数溢出报错其实源于业务逻辑误用,而非配置太小:
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
- 在 HTTP
onRequest中直接end(file_get_contents('video.mp4'))—— 大文件读进内存再一次性发,必然超限。应改用sendfile()或流式write()+ 分块 - WebSocket
push()传了未压缩的 JSON 数组(如含大量日志或原始图片 Base64),体积远超 2MB 默认值。建议前端压缩或服务端提前序列化+gzip - 框架封装层(如 think-swoole)内部调用了
end(),但你传入的视图模板渲染后内容过大。可临时加strlen($html) > 1024*1024判断并降级处理
合理调整 buffer_output_size 的实操建议
如果确认是合法的大响应(如导出报表 PDF、API 返回完整数据集),再考虑调参,但必须配合监控:
- 从
128 * 1024(128KB)起步测试,逐步翻倍,避免一步设到 32MB 导致单次错误消耗过多内存 - 搭配
http_compression => true,对文本类大响应可减少 60%+ 传输量,比单纯扩 buffer 更有效 - v4.6.7+ 版本默认已提至
UINT_MAX,但不建议依赖默认值——显式设置能明确传达业务意图,也方便团队协作排查 - 上线后用
swoole_get_local_statistics()检查server.output_bytes和server.request_count比值,若平均单请求输出 > 5MB,说明设计上可能需要引入异步下载或分页
真正的大包传输,应该绕开 end/send 的方案
当数据持续大于 1MB,且需可靠送达时,buffer_output_size 就不该是主力解法:
- HTTP 场景:用
sendfile()直接让内核送文件,零拷贝,不走 PHP 内存;或用chunked transfer encoding+ 循环write(),每次控制在 64KB 内 - WebSocket 场景:启用
websocket.compress,或约定协议分帧(如每帧 ≤ 64KB,带 sequence id),由客户端拼接 - 长连接推送场景(如直播):改用
socket_buffer_size配合流量控制——客户端主动发 ACK 后再推下一帧,避免服务端缓存堆积










