协程调用数据库不等于自动高并发,因其仍受连接资源争抢、下游限流、驱动兼容性三重制约;必须启用协程Hook、改用Co\MySQL等协程客户端、强制接入连接池三者缺一不可。

能提升,但前提是配置正确、代码适配、连接池到位——否则并发一上来就报 EMFILE 或卡死 Worker。
为什么协程调用数据库不等于自动高并发
很多人以为只要用了 Co\MySQL 或启用了 Runtime::enableCoroutine(),PDO 就会“变快”。事实是:协程只解决 I/O 等待的线程阻塞问题,不解决连接资源争抢、下游限流、驱动兼容性这三座大山。
-
Co\MySQL是协程安全的,但原生PDO(哪怕加了PDO::ATTR_TIMEOUT)仍走libmysqlclient.so同步阻塞路径,会劫持整个协程调度器线程 - 没配连接池时,1000 个并发协程可能尝试建 1000 个 MySQL 连接,而
max_connections=200→ 大量连接失败或排队等待 - 即使开了
SWOOLE_HOOK_ALL,PDO默认不被 Hook;必须显式用Co\MySQL或Swoole\Coroutine\MySQL才真正协程化
必须做的三件事,缺一不可
不是“换一个类就能提速”,而是整套协作机制要对齐。
- 启用协程 Hook:
Runtime::enableCoroutine(SWOOLE_HOOK_ALL)(PHP 8.1+ 推荐),且确保在 Server 启动前调用 - 改用协程客户端:
Co\MySQL替代PDO;若必须用 PDO 风格,可用Swoole\Coroutine\MySQL(它提供 PDO-like API,但底层是协程驱动) - 强制接入连接池:
Swoole\Coroutine\Pool管理连接,设max_idle_time和max_active,比如max_active => 50,避免连接数爆炸
常见翻车现场和对应解法
压测时突然响应变慢、大量超时、Worker 进程 CPU 100% 却无请求处理?大概率掉进下面这些坑。
立即学习“PHP免费学习笔记(深入)”;
- 错误写法:
new Co\MySQL()放在协程外或循环里反复 new → 每次都新建连接,池失效。✅ 正确:从Pool->get()获取,用完->put() - 漏设超时:
$mysql->connect()不传timeout参数 → 协程卡住,拖垮整个 Worker。✅ 必须设:['timeout' => 2.0] - 混用同步函数:协程里调了
file_get_contents()或未 Hook 的cURL→ 调度器冻结。✅ 查swoole_get_status()的coroutine_peak_num是否异常飙升 - MySQL 服务端版本太老(如 5.6)+
libmysqlclient.so旧版 → 即使协程客户端也会 fallback 到阻塞调用。✅ 升级到 MySQL 8.0+ 并确认 client lib 版本 ≥ 8.0.22
真正的瓶颈往往不在协程本身,而在你是否让每个协程只做它该等的事、等多久、等谁。连接池配错、超时没设、驱动没换——这些细节比“用不用协程”更能决定并发上限。



















