必须用Swoole协程MySQL客户端替代PDO/mysqli,因后者同步阻塞、不支持协程调度;需在协程内new并connect,host禁用localhost防DNS阻塞,连接池须预热、获取后ping检测、用完归还而非close,query须try-catch处理2006/2013错误。

要在高并发Web服务中避免MySQL连接频繁创建销毁导致的响应延迟和数据库负载激增,必须用Swoole协程MySQL客户端替代传统PDO或mysqli同步调用。这要求你严格遵循协程生命周期、连接复用逻辑和异常处理路径,否则极易出现连接泄漏或查询阻塞。
初始化协程MySQL客户端
在协程内实例化客户端,不能在全局或WorkerStart外创建:用 new Swoole\Coroutine\MySQL() 实例化对象,立即调用 connect() 并传入完整配置数组。
【host必须填127.0.0.1而非localhost】,否则会触发DNS解析阻塞,协程挂起超时;port、user、password、database四项缺一不可,空字符串或null会导致连接静默失败。
连接失败时不要重试——直接抛出异常,由上层协程捕获并记录日志,避免无限循环消耗资源。
执行查询与事务控制
方法一:单条查询直接调用query(),返回结果数组或false。例如:$mysql->query('SELECT id FROM users WHERE status=1')。
方法二:带参数的查询必须用prepare+execute防止SQL注入。先$stmt = $mysql->prepare('SELECT * FROM orders WHERE user_id = ? AND status = ?'),再$stmt->execute([1001, 'paid'])。注意prepare返回false时说明SQL语法错误,不能跳过检查直接execute。
事务操作必须显式调用begin()→query()→commit()或rollback()。若中间任意一步失败,必须执行rollback,否则连接将处于未结束事务状态,后续query会报错“Commands out of sync”。
连接池集成(推荐生产环境)
第一步:在WorkerStart回调中初始化连接池通道,容量设为10~50之间,根据QPS预估设定:$pool = new Swoole\Coroutine\Channel(20)。
第二步:启动时预热连接,循环20次执行connect并成功后push进channel,失败连接直接丢弃不入池。
第三步:业务协程中用$mysql = $pool->pop(500)获取连接,500是毫秒级超时,防止请求卡死;查询结束后必须$pool->push($mysql)归还,【严禁调用close()或unset()】,否则连接永久丢失。
第四步:每次pop前可加ping检测,若$mysql->ping() === false则重建新连接再push,避免使用已断开的句柄。
错误处理与超时设置
所有query调用必须包裹try-catch,捕获Swoole\Coroutine\MySQL\Exception,重点识别错误码2006(MySQL server has gone away)和2013(Lost connection),这两种情况需重建连接并重试当前SQL。
在connect配置数组中加入'timeout' => 3(单位秒),防止网络抖动时协程无限等待;query默认无超时,需手动在SQL前加/*+ MAX_EXECUTION_TIME(2000) */提示MySQL强制中断超时查询。
协程内不得使用sleep()模拟延时,应改用co::sleep(0.1),否则会阻塞整个协程调度器。


















