socket_buffer_size设过大易致内存耗尽,过小则触发“output buffer has been overflowed”错误;它控制每连接双向缓冲区总和,需据连接数、数据特征及系统wmem_max综合调优。

socket_buffer_size 不是越大越好,设错反而会吃光内存或触发 overflow 错误。
为什么 socket_buffer_size 会触发 send failed 报错
当客户端接收速度跟不上服务器发送节奏时,未发出的数据会堆积在 Swoole 的写缓冲区里。一旦超过 socket_buffer_size 限制,Swoole 就会拒绝继续写入,并报错:swFactoryProcess_finish:send failed,session#1 output buffer has been overflowed。
这个错误只影响当前连接,其他连接不受干扰,但说明你的缓冲区已成瓶颈。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
- 常见于带宽差异大的场景:比如 A 用户 100Mbps、B 用户 1Mbps,同一时间发 10MB 数据,B 的缓冲区几秒就满
- 不是网络断了,而是 Swoole 主动“堵住”了发送通道,防止内存无限增长
- 该参数控制的是每个连接的**双向缓冲区总和**(读 + 写),不是单次 send 大小(那是
buffer_output_size)
不同业务场景下怎么设 socket_buffer_size
设值必须结合连接数、单连接数据特征、系统内核限制三者权衡,不能套模板。
- 高频小包(IM 心跳、RPC 请求):建议
8192~32768(8K–32K)。连接数上万时,设太大直接吃光内存 - 文件上传 / 视频流:可设到
1048576(1MB)甚至2097152(2MB),但要确认系统net.core.wmem_max允许(用sysctl net.core.wmem_max查) - 长连接网关 / WebSocket:优先压到
65536(64K)以内,连接数超 5000 时,每多 1KB 就多占 5MB 内存 - Hyperf 等框架中,若启用了协程 Redis/MySQL 客户端,它们内部也受此参数影响,需统一评估
怎么验证和调优 socket_buffer_size
不能只看文档推荐值,得看实际运行时的表现和系统约束。
- 启动后用
var_dump($server->setting['socket_buffer_size'])确认是否生效,避免配置被覆盖 - 压测时监控
swoole.log是否出现output buffer has been overflowed,有则说明值偏小 - 用
ss -i或cat /proc/net/snmp观察 TCP 缓冲区实际使用情况,判断是否长期高位占用 - 修改前先调大系统限制:
sudo sysctl -w net.core.wmem_max=4194304(4MB),否则 Swoole 设再大也无效 - 调整后必须重启服务,该参数不支持热更新
真正难的不是设一个数字,而是理解你每个连接平均会积压多少字节、能容忍丢帧还是必须保序、磁盘能否接得住落库压力——这些决定了你是该增大缓冲区,还是改用消息队列+通知拉取模式。










