max_connection 是 swoole 进程级连接上限,受 ulimit -n 硬限制;若设置过大则被自动截断或修正为 ulimit 值,过小则启动报错并修正。

max_connection 是 Swoole 自己的连接数上限
max_connection(或别名 max_conn)是 Swoole Server 实例级配置项,它控制的是当前这个 Swoole 进程最多允许维持多少个活跃 TCP 连接。Swoole 会用它来预分配内存块(比如 swConnection 结构体数组),并参与 session ID 映射、连接统计等内部管理。
关键点在于:它不直接决定“能不能 accept 新连接”,而是影响“accept 之后能否成功注册进事件循环”。如果设得太小,Swoole 启动时会报错 serv->max_connection is too small,并自动修正为系统 ulimit -n 的值;如果设得太大(比如超 100 万),可能因内存分配失败而启动失败——尤其在 4.2.9+ 版本中,底层会主动截断为 10000 以防爆内存。
ulimit -n 是操作系统对单进程打开文件描述符的硬限制
Linux 每个 TCP 连接占用一个文件描述符(fd),Swoole 的每个连接也对应一个 fd。所以 ulimit -n 实际上是 Swoole 能达到 max_connection 的物理天花板。
常见错误现象包括:
- 明明设置了
'max_conn' => 65535,但实际只接受到 ~1024 个连接就卡住 - 日志里反复出现
accept(): Too many open files或Too many open files (errno=24) - 用
lsof -p $PID | wc -l查到 fd 数已接近ulimit -n输出值
这时候不是 Swoole 配置错了,而是系统没放开限制。必须先执行 ulimit -n 65536(临时)或在 systemd service 文件里配 LimitNOFILE=65536(持久)。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
两者不匹配时 Swoole 会怎么处理
Swoole 在启动阶段会做一次校验,行为取决于版本和数值关系:
- 若
max_conn > ulimit -n:输出警告WARN swServer_start_check: serv->max_conn is exceed the maximum value[...],并强制重置为ulimit -n的值 - 若
max_conn :触发 fatal error,拒绝启动 - 若
ulimit -n被设得极高(如 100 万),而 Swoole 版本 ≥ 4.2.9,则max_conn会被静默 capped 到 10000——这是防止预分配内存过大导致 OOM
也就是说:max_conn 是你“想管多少”,ulimit -n 是系统“准你管多少”,而 Swoole 会在中间强行拉齐,且优先服从系统限制。
为什么不能只调大 ulimit 就完事
光提高 ulimit -n 不等于服务就能稳撑高并发。因为:
- Swoole 每个连接固定占约 224 字节(1.9.16+ 版本),10 万连接 ≈ 22MB 内存仅用于连接元数据;再叠加协程栈、buffer、task worker 开销,总内存增长非线性
- 内核 socket backlog 队列(
net.core.somaxconn)若太小,会导致新连接在进入 accept 前就被丢弃,表现为客户端 connect timeout - 未启用
enable_reuse_port时,多个 worker 共享一个 listen fd,容易在高并发下出现 accept 饥饿,此时即使ulimit和max_conn都够,连接也无法均匀分发
真正要压测出稳定连接数,得同步检查三处:Swoole 的 max_conn、系统的 ulimit -n、内核的 net.core.somaxconn,缺一不可。其中最容易被忽略的是 somaxconn,它默认常为 128,远低于业务预期。










