Laravel 无内置连接池,仅在 Octane+Swoole 下 pool 配置生效;FPM 环境下连接数由 PHP-FPM worker 数×每请求连接数决定,受 MySQL max_connections 限制,需通过连接管理、超时设置和压测监控防泄漏。

MySQL 连接池最大连接数由 max_connections 控制,Laravel 自身不实现连接池
Laravel 的数据库层(基于 PDO)是无状态、按需建立连接的,它没有内置连接池。所谓“连接池限制”,实际是约束 Laravel 应用向 MySQL 发起的并发连接上限,防止打爆数据库或耗尽 PHP 进程资源。
关键点在于:Laravel 用的是连接复用(connection reuse),不是连接池(connection pooling)。真正起作用的是 MySQL 服务端的 max_connections 和 Laravel 配置里的 pool 参数(仅对某些驱动如 pdo_mysql 有间接影响)。
- PHP-FPM 每个 worker 启动时可能新建连接,worker 数 × 每个请求的活跃连接数 = 实际并发连接峰值
-
DB::connection()->getPdo()拿到的是 PDO 实例,每次执行query或select不一定新建连接,但事务中或长生命周期对象(如队列任务里未释放)容易滞留连接 - 如果你用的是 Laravel Octane + Swoole,
pool配置才真正生效——它会预创建并复用固定数量的连接,此时必须配pool.max_connections
config/database.php 中的 pool 配置只在 Octane 下有效
很多人在普通 FPM 环境下也配了 'pool' => ['max_connections' => 10],但这完全没用——PDO 默认不启用连接池逻辑,Laravel 也不会拦截或复用连接。
只有在 Octane + Swoole 或 RoadRunner 场景下,这个配置才被读取并用于初始化连接池实例。
- Octane 默认不开启连接池,需显式设置:
'pool' => ['max_connections' => 20, 'min_connections' => 5] - 若
max_connections设太小(比如 5),高并发时会出现PDOException: SQLSTATE[HY000] [1040] Too many connections - 若设太大(比如 200),而 MySQL 的
max_connections是 151(默认值),就会直接失败,错误信息是SQLSTATE[HY000] [1040] - 注意:Swoole 的连接池和 MySQL 的
wait_timeout冲突,空闲连接可能被服务端主动断开,需配合pool.ping_interval心跳检测
查清真实连接数:别只看 SHOW PROCESSLIST
SHOW PROCESSLIST 只显示当前活跃连接,但很多连接处于 Sleep 状态却未释放,尤其在长生命周期上下文(如队列任务、WebSocket handler)中调用了 DB::connection()->reconnect() 或手动 DB::purge() 失败后残留。
更准的方法是结合 MySQL 状态变量:
- 运行
SHOW GLOBAL STATUS LIKE 'Threads_connected';—— 当前总连接数(含 Sleep) - 对比
SHOW VARIABLES LIKE 'max_connections';—— 看是否逼近上限 - 查 Laravel 日志里有没有重复出现
Too many connections,说明应用层连接未及时 close 或复用失控 - 用
lsof -i :3306 | grep php在服务器上确认 PHP 进程实际打开的 socket 数量(FPM 下每个 worker 一个连接很常见)
防止耗尽的关键动作:关连接、控并发、设超时
不靠“池”来防爆,靠的是连接生命周期管理 + 请求节流 + 数据库侧兜底。
- 避免在循环里反复调用
DB::connection();用一次连接做多次操作,或显式$conn->disconnect()(仅 Octane 场景推荐) - 队列任务中务必用
DB::afterCommit()或DB::transaction()显式控制边界,防止事务锁住连接过久 - 在
config/database.php的 MySQL 配置里加'options' => [PDO::ATTR_TIMEOUT => 5],防止慢查询长期占着连接 - 给 MySQL 配置
wait_timeout=60和interactive_timeout=60,让空闲连接更快释放(注意:这会影响 Laravel 的长连接重用策略) - 上线前压测时,盯紧
Threads_connected增长曲线——如果随 QPS 线性上涨且不回落,基本就是连接泄漏了
最常被忽略的是:你以为在用连接池,其实只是在不断新建连接;你以为设置了 max_connections 就安全了,但它只在 Octane 下起效,而你的生产环境大概率跑在 FPM 上。


















