Hyperf 队列任务必须显式指定数据库连接名,禁止依赖默认连接;应在 handle() 中调用 Db::connection('xxx'),模型需设 protected $connection;禁在构造函数中初始化 DB 实例;队列库应独立配置连接池并验证生效。

Hyperf 队列消费任务默认不绑定任何数据库连接,若 Job 中直接使用 Db::connection() 且未显式指定连接名,会走 default 连接池——这在多库项目中极易导致写错库、读错表、事务失效等问题。必须让每个 Job 明确、稳定地使用目标数据库连接。
明确声明连接名,禁止依赖默认配置
在 Job 类的 handle() 方法中,所有数据库操作都需通过 Db::connection('xxx') 指定连接名,不能省略参数或依赖全局 default:
- 错误写法:
Db::insert(...)或Db::connection()->table(...)—— 会走 config/autoload/db.php 中的 default 配置,与业务意图脱节 - 正确写法:
Db::connection('order_db')->table('orders')->insert(...),其中order_db必须已在 db.php 中正确定义 - 若用 Eloquent 模型,需在模型类中显式设置:
protected $connection = 'order_db';
避免协程上下文污染导致连接错配
Hyperf 的协程上下文(Context)不会自动透传数据库连接配置。Job 构造函数中禁止初始化 DB 实例或缓存 connection 对象,否则可能被多个协程复用,引发连接错乱:
- 禁止在
__construct()中调用Db::connection('log_db')并赋值给属性 - 所有 DB 操作必须延迟到
handle()内执行,并每次重新获取连接实例 - 如需复用查询构建器,可在 handle 内部定义局部变量,不跨协程生命周期保存
连接池独立配置,防止资源争抢
队列消费者进程长期运行,其使用的数据库连接池应与 HTTP 请求隔离,避免因接口高并发挤占队列连接资源:
- 在
config/autoload/db.php中为队列专用库单独定义连接,例如'queue_log',并设置'max_connections' => 20 - 确保该连接池的
wait_timeout≥ 5.0,max_idle_time≤ 30.0,防止空闲连接被 MySQL 主动断开 - 在 Job 中严格使用
Db::connection('queue_log'),不混用'cache_db'或'user_db'
验证连接是否生效的简单方法
可在 Job 的 handle() 开头加一行日志,输出当前连接的实际 host 和 database:
$conn = Db::connection('finance_db'); logger()->info('DB Host', ['host' => $conn->getConfig('host'), 'db' => $conn->getConfig('database')]);- 部署后检查日志,确认输出与预期完全一致,而非 fallback 到 default 的配置
- 配合
SHOW PROCESSLIST观察 MySQL 端实际连接来源,双重验证


















