MySQL连接数打满本质是Hyperf连接池失控与服务无隔离,需检查三点:max_connections是否按服务等级显式配置、max_idle_time是否≤240秒、是否开启连接泄漏检测。

Hyperf 项目中 MySQL 连接数打满,本质不是数据库扛不住,而是连接池失控 + 服务间无隔离。问题常在高并发时集中爆发,报错 Too many connections,但根源几乎都在应用层配置和代码逻辑里。
必须立刻检查的三个关键点
-
max_connections在每个数据库连接配置里是否被显式写死?
默认值(如10或100)若未按服务等级划分,多个服务一齐拉满就会雪崩。比如总max_connections=200,5个服务各设100,启动即满。 -
max_idle_time是否 ≤ 240 秒?
若设为60秒以上,而 MySQL 的wait_timeout=28800(8小时),连接在池中“假活”——DB早断了,应用还留着,堆积大量Sleep状态连接。 - 是否开启连接泄漏检测?阈值是否设在 60–120 秒?
泄漏不拦截,调大任何参数都只是拖延崩溃时间。
Hyperf 中必须改的配置项(config/autoload/databases.php)
'default' => [
'driver' => 'mysql',
// ... 其他基础配置
'pool' => [
'min_connections' => 2,
'max_connections' => 20, // ✅ 按服务等级设死,核心服务可给30–40,查询类限10–15
'connect_timeout' => 3.0, // ✅ 压到3–5秒,防卡住不释放
'wait_timeout' => 3.0, // ✅ 必须 ≥ max_idle_time,否则池子提前拒绝请求
'max_idle_time' => 180.0, // ✅ 推荐180秒(3分钟),强于默认60秒但不过激
'heartbeat' => -1,
],
],⚠️ 注意:Hyperf 不会自动继承全局配置,每个数据库连接必须单独配
pool.max_connections,不能依赖框架默认值。
快速验证连接池是否健康
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
登录 MySQL 执行:
SELECT id, user, host, db, command, state, time, info FROM information_schema.processlist WHERE state = 'Sleep' AND time > 180 ORDER BY time DESC LIMIT 5;
如果 time 列普遍超 180 秒,说明 max_idle_time 没生效,或被中间件/ORM 绕过(比如手动 getConnection() 后没归还)。
代码层高频踩坑点
- 手动获取连接后,未在
finally或try-catch-finally中调用->close()或交还给池; - 在事务中调用 HTTP/RPC/文件读写等耗时操作,导致连接长期挂起;
- 使用
DB::transaction()但异常分支没回滚,连接卡在Sleep状态; - 多实例部署时,每个实例都按最大配额开连接,总量翻倍打爆 DB。
上线前必做两件事
- 用
SHOW PROCESSLIST按host和user分组统计,确认没有某个服务占掉 70%+ 连接; - 压测时监控
Threads_connected和Threads_created:后者持续上涨,就是连接频繁新建销毁,大概率是短连接风暴或泄漏。
不复杂但容易忽略。

















