workerman 5.2.3对接mysql必须在onworkerstart中为每个worker独立初始化协程连接(workerman\mysql\connection),主动ping检测并异常重建,禁用pdo及持久连接,所有操作需await且包裹try-catch处理2006错误。

Workerman 5.2.3 对接 MySQL 数据库,核心不是版本号差异,而是延续 Workerman 常驻进程模型下的连接管理原则:每个 worker 子进程必须独立初始化、主动检测、异常重建。5.2.3 版本已原生支持协程,推荐使用 workerman/mysql 协程客户端,而非传统 PDO。
必须在 onWorkerStart 中初始化连接
不能在 onMessage 或全局作用域 new 连接实例,否则会因常驻内存导致连接堆积、复用失效连接,最终触发 “MySQL server has gone away” 或 “Too many connections”。正确做法是:每个 worker 启动时单独创建一个连接,并绑定到该进程上下文。
- 用
$worker->db或global $db存储连接实例,确保单 worker 内复用 - 避免使用
PDO::ATTR_PERSISTENT => true,它在 fork 模型下极易引发句柄继承错误 - 若用
Workerman\MySQL\Connection(非协程版),需手动 ping;若用协程版(Workerman\Mysql\Connection),也建议首次 query 前显式 ping
推荐使用协程 MySQL 客户端(workerman/mysql)
Workerman 5.2.3 内置协程运行时(基于 Revolt),搭配 workerman/mysql 可实现真正非阻塞查询,语法简洁且自动适配连接池语义。
- 安装:
composer require workerman/mysql - 初始化示例(放在
onWorkerStart中):
$worker->onWorkerStart = function ($worker) {
$worker->db = new Workerman\Mysql\Connection(
'127.0.0.1', 3306, 'user', 'pass', 'dbname'
);
// 主动探测连接有效性
if (!$worker->db->ping()) {
unset($worker->db);
$worker->db = new Workerman\Mysql\Connection(...);
}
};
```
查询写法与错误处理要适配协程模型
所有数据库操作返回 Promise(可 await),不能混用同步阻塞调用。捕获 “gone away” 错误后,需重建连接并重试,不能简单 throw。
- 基础查询:
$rows = await $worker->db->select('*')->from('users')->where(['id' => 123])->query(); - 单行/单值:
$user = await $worker->db->row("SELECT * FROM users WHERE id = ?", [123]); - 写入操作同样支持 bindValues 和链式构建,如
insert()、update() - 务必在 try-catch 中包裹查询,并对
mysqli_sql_exception或特定错误码(如 2006)做重连逻辑
确认 PHP 环境支持 MySQL 扩展
报错如 Undefined class constant 'MYSQL_ATTR_INIT_COMMAND' 或连接失败,大概率是 PHP 缺少必要扩展,与 Workerman 无关。
- 运行
php -m | grep -E 'pdo|mysql',确保输出含pdo和pdo_mysql - Ubuntu/Debian(PHP 8.x):
sudo apt install php-mysql - CentOS/RHEL(PHP 7+):
yum install php70w-pdo php70w-mysqlnd - 禁用
mysqlnd或仅装mysqli不够,必须有pdo_mysql











