laravel-swoole性能瓶颈主因是worker_num、max_request和数据库协程驱动配置错误:worker_num宜设4~8(4核服务器),max_request推荐1000~3000,database需显式启用mysql-coroutine驱动并关闭静态文件处理。

直接说结论:Laravel-Swoole 的配置不是“越复杂越好”,而是要根据实际部署场景、并发模型和资源限制做取舍;多数项目卡在性能瓶颈,根本原因不是没开协程,而是 worker_num、max_request 和数据库连接复用这三项配错了。
worker_num 设多少才不翻车
这个值决定 Swoole 启动多少个工作进程处理请求。设太高会争抢 CPU、触发频繁上下文切换;设太低则压根跑不满机器资源。
- 常规 4 核服务器,
worker_num推荐设为4~8,不要盲目套用“CPU核数×2”这种过时建议 - 如果应用重度依赖 MySQL 或 Redis(比如每个请求都查库),反而要适当降低,避免单机建立过多连接打爆数据库(例如
worker_num=4+ 每个 worker 最多 10 个 MySQL 连接 = 40 连接,远低于默认 MySQL max_connections=151) - 线上观察
ps aux | grep swoole,若大量进程处于R(运行)或D(不可中断睡眠)状态,说明worker_num已超载
max_request 配置不当会导致内存泄漏静默爆发
max_request 控制每个 worker 处理多少请求后自动重启。它不是“防泄漏万能开关”,而是给内存缓慢增长留出兜底窗口。
- 默认值
0(永不重启)在 Laravel-Swoole 中极危险:Eloquent 查询缓存、静态变量残留、未释放的 Redis 连接都会累积 - 生产环境建议设为
1000~3000,具体看单请求平均内存增长量(可用memory_get_peak_usage()日志采样) - 切勿设成
100这类极小值——高频重启带来上下文重建开销,反而拖慢吞吐,且掩盖了真实泄漏点
database 配置必须显式启用协程驱动
Laravel-Swoole 默认仍走传统 PDO,协程 MySQL 不会自动生效。不改这里,worker_num 再高也白搭,数据库仍是串行阻塞点。
- 确认
config/database.php中 MySQL 连接的'driver'改为'mysql-coroutine' - 检查
config/swoole_http.php的'coroutine.mysql'是否设为true - 务必关闭
DB::connection()->getPdo()这类直接拿原生 PDO 的写法——协程连接器无法接管,会退化为同步阻塞 - 事务内所有操作必须在同一个协程内完成,跨协程调用
DB::transaction()会报错或连接错乱
静态资源交给 Nginx,别让 Swoole 跑 JS/CSS
Swoole 是网络服务器,不是 Web 服务器。让它处理静态文件不仅浪费协程资源,还会因文件 I/O 阻塞整个 worker。
- 在
config/swoole_http.php中把'enable_static_handler'设为false - Nginx 配置里加
location ~* \.(js|css|png|jpg|gif|ico|svg)$ { try_files $uri @laravel; },把静态请求全拦住 - 若误开启静态处理,
ab -n 10000 -c 100压测时会出现大量502 Bad Gateway或响应时间陡增,本质是 worker 被文件读取卡死
真正难调的从来不是参数本身,而是不同配置之间的耦合效应——比如开了 mysql-coroutine 却没关 enable_static_handler,结果静态文件把协程占满,数据库连接池反而饿死。上线前务必用真实接口路径压测,而不是只测 /。











