Laravel没有真正的数据库连接池,config/database.php中的pool和sticky配置无效;MySQL连接复用依赖PHP-FPM进程内PDO实例复用,MongoDB驱动才支持真连接池。

Laravel 没有真正的数据库连接池,所谓“配连接池”是无效操作。 你往 config/database.php 里加 'pool' => ['min' => 5, 'max' => 20] 或 'sticky' => true,框架压根不读——这些键在 Laravel 9+ 源码里只是占位符,DatabaseManager 中搜索不到实际使用逻辑。
为什么 config/database.php 里的 pool 和 sticky 完全没用
这些配置项既不被 ConnectionFactory 解析,也不参与连接创建或路由。Laravel 的 MySQL/PostgreSQL 连接完全依赖 PHP-FPM 进程内 PDO 实例复用,不是连接池模型。你在配置里写 'pool' => ['enabled' => true],只会让团队误以为开了池,实际毫无效果。
-
sticky只出现在单元测试和注释里,真实读写分离必须靠显式调用DB::connection('write')或自定义Connection类 -
pool键未在任何核心类中被array_key_exists()或??访问过,硬加进去等于注释 - 试图用它控制“连接复用数量”或“事务粘性”,结果只会白忙活 + 增加维护成本
MySQL 场景下真正有效的连接复用方式
PHP-FPM worker 进程内,只要不手动调用 DB::disconnect(),且 PDO 构造时没开 PDO::ATTR_PERSISTENT => true(默认就是 false),底层 mysqli 或 pdo_mysql 驱动就会自动复用 TCP 连接。重点是避免破坏这个复用链。
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
- 不要在循环里反复调用
DB::connection(),改用一次获取后复用:$conn = DB::connection(); $conn->table(...)->get(); - 确认同一次请求中
DB::connection()->getPdo()返回的是同一个对象(可var_dump()验证) - 禁用持久连接:确保
'options' => [PDO::ATTR_PERSISTENT => false]—— 虽然默认如此,但有人会手抖改成true,导致连接泄漏 - 队列任务或 Swoole 长进程里,
wait_timeout触发后抛出"MySQL server has gone away",此时DB::reconnect()只是新建连接,不重试原 SQL;应捕获QueryException并检查$e->getPrevious()->getMessage()
MongoDB 是唯一支持真连接池的场景
Laravel MongoDB 驱动(基于官方 PHP MongoDB 扩展)确实支持连接池,靠 maxPoolSize 和 minPoolSize 控制,但这和 Eloquent/MySQL 完全无关,别混用。
- 配置位置:在
config/database.php的'mongodb'连接块内,'options' => ['maxPoolSize' => 15, 'minPoolSize' => 5] - 必须启用
'persistConnection' => true才能复用连接;否则每次请求都重建 -
socketTimeoutMS和connectTimeoutMS要设合理值(如30000和10000),否则空闲连接被中间设备断开后无感知 - 注意:这是 MongoDB PHP Driver 的行为,不是 Laravel 框架能力;换 MySQL 驱动就失效
最常被忽略的点:连接是否复用,取决于 PHP-FPM worker 生命周期和 PDO 实例存活状态,而不是配置文件里写了什么“pool”。盯着 config/database.php 加参数,不如用 strace 看看实际有没有重复 connect() 系统调用。

















