Node.js中@mysql/xdevapi的MySQL X DevAPI重连逻辑报错排查
问题分析
你遇到的错误是因为直接访问了@mysql/xdevapi模块的私有内部属性_client和_stream,这些属性不属于官方公开API的一部分,模块内部实现可能随时变更,在v8.0.33版本中session对象并没有对外暴露_client属性,因此会抛出Cannot read properties of undefined的错误。
正确的重连实现方案
不要依赖私有属性,使用官方提供的Session对象事件监听能力,结合合理的重连逻辑来实现需求:
const mysqlx = require('@mysql/xdevapi'); // 数据库配置抽离,方便复用 const dbConfig = { user: 'your_user', password: 'your_password', host: 'your_host', port: 33060 }; // 保存当前有效session实例,供业务逻辑调用 let currentSession; async function createSession() { try { // 清理旧session,避免资源泄漏 if (currentSession) { try { await currentSession.close(); } catch (err) { console.warn('关闭旧session失败:', err.message); } } const session = await mysqlx.getSession(dbConfig); currentSession = session; console.log('数据库连接成功'); // 用官方API监听连接关闭事件 session.on('close', () => { console.log('连接已断开,3秒后尝试重连...'); setTimeout(createSession, 3000); }); // 示例:定时检查连接可用性 async function checkConnection() { if (!currentSession || !currentSession.isOpen()) { console.log('session未就绪,跳过检查'); return; } try { const result = await currentSession.sql('SELECT 1').execute(); console.log('连接正常,查询结果:', result.fetchAll()); } catch (err) { console.error('连接异常:', err.message); } } setInterval(checkConnection, 5000); } catch (error) { console.error('连接失败:', error.message); // 连接失败后自动重试 setTimeout(createSession, 3000); } } // 初始化连接 createSession();
关键说明
- 使用官方事件监听:
Session对象本身继承自EventEmitter,直接通过session.on('close', callback)监听连接关闭是官方支持的方式,不会受内部实现变更影响。 - 管理session实例:用全局变量保存当前有效的session,业务逻辑中可通过
session.isOpen()判断连接状态,避免无效操作。 - 添加重试间隔:连接失败或断开后,加入固定间隔重试,避免短时间内频繁请求导致资源耗尽。
- 旧session清理:重连前关闭旧session,防止未释放的资源堆积。
内容的提问来源于stack exchange,提问作者Alok
相关产品推荐
相关产品推荐

