ab压测Swoole HTTP服务QPS上不去的主因是客户端连接数、服务端协程调度与Linux内核参数未对齐;需调优worker_num、max_coroutine、enable_reuse_port、reactor_num等Swoole配置,并同步调整net.core.somaxconn、ulimit -n等系统参数,否则高并发下连接丢弃、协程创建失败或CPU负载不均将导致QPS卡在2k–3k。

用 ab 测 Swoole HTTP 服务时为什么 QPS 上不去
直接拿 Apache Bench(ab)压测默认配置的 Swoole HTTP Server,常卡在 2k–3k QPS,不是代码慢,而是客户端连接数、服务端协程调度和内核参数没对齐。
-
ab -n 10000 -c 1000这种高并发请求会触发 Linux 默认的net.core.somaxconn(通常为 128),导致大量连接被丢弃或排队,ab报错如socket: Too many open files或超时 - Swoole 默认启用
enable_reuse_port = false,单进程无法充分利用多核,CPU 利用率不均 - 未开启
http_compression或buffer_output_size不合理,小响应体频繁 flush,增加协程切换开销
Swoole Server 启动时必须调的几个关键配置项
这些不是“可选优化”,而是压力场景下的基础保底配置,漏掉任意一个都可能让压测结果失真。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
-
worker_num设为 CPU 核心数 × 2(例如 8 核设为 16),避免单 worker 成瓶颈;若用task_worker_num处理耗时逻辑,需额外预留资源 -
max_coroutine至少设为worker_num × 3000,否则高并发下协程创建失败,日志出现coroutine limit reached - 务必开启
enable_reuse_port = true,让多个 worker 绑定同一端口,真正实现负载分散 -
reactor_num建议设为 CPU 核心数(最低 4),太少会导致事件分发延迟,压测中表现为 P99 延迟陡增
Linux 内核与 ulimit 必须同步调整
Swoole 是用户态网络栈,但底层仍依赖系统 socket 和文件描述符,不调系统参数,再好的 PHP 配置也白搭。
- 临时生效:
sysctl -w net.core.somaxconn=65535、sysctl -w net.ipv4.ip_local_port_range="1024 65535" -
ulimit -n 100000要在启动 Swoole 进程的 shell 环境中执行(systemd 启动需在[Service]段加LimitNOFILE=100000) - 检查是否生效:
cat /proc/$(pgrep php)/limits | grep "Max open files",确认LimitNOFILE值已更新
真实压测时怎么避免“假瓶颈”
很多团队压出低 QPS 就归咎于 Swoole,其实往往是测试方式或监控盲区导致误判。
- 别只看
ab的平均 QPS:用ab -g data.tsv导出原始数据,用 gnuplot 或 Excel 查 P95/P99 延迟分布,突刺往往藏在尾部延迟里 - 用
swoole_server->stats()实时查connection_count、tasking_num、request_count,如果tasking_num持续 > 0,说明 task worker 已饱和 - 禁用 Xdebug、APM 扩展(如 Tideways)、PHP 错误日志全开等调试组件——它们会让压测结果偏差 3–5 倍
ulimit -n 和 enable_reuse_port 这两个开关——它们不开,其余全调对也没用。


















