You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DiscordJS机器人在线数小时后MySQL连接失效求助

问题根源与解决方案

你的问题确实是MySQL连接因闲置超时被服务器自动关闭导致的。MySQL默认的wait_timeout和interactive_timeout参数值为8小时(28800秒),刚好和你描述的机器人在线8-10小时后出问题的时间线完全吻合。当连接被服务器主动断开后,你的代码仍在复用这个失效的连接对象,执行查询时无法获取正常结果,result变量因此变为undefined,进而触发读取length属性的报错。

从你提供的连接代码来看,你使用createConnection创建了单个长连接,这种方式没有内置的自动重连机制,长时间闲置后必然会遇到连接断开的问题。


推荐解决方案

1. 使用连接池替代单连接(最稳妥方案)

mysql2的连接池会自动管理连接生命周期:当连接失效时自动重建,按需分配连接,彻底解决闲置断开问题,同时还能提升并发查询性能。

示例代码:

const mysql = require('mysql2/promise'); // 优先使用Promise版本,适配async/await语法

// 创建连接池
const pool = mysql.createPool({
    host: 'ip',
    user: 'username',
    password: 'password',
    database: 'database_name',
    waitForConnections: true,
    connectionLimit: 10, // 根据机器人并发需求调整
    queueLimit: 0
});

// 封装查询函数
async function executeQuery(sql, params = []) {
    const [rows] = await pool.execute(sql, params);
    return rows;
}

// 使用示例
async function getUser(userId) {
    try {
        const user = await executeQuery('SELECT * FROM users WHERE id = ?', [userId]);
        return user.length > 0 ? user[0] : null;
    } catch (err) {
        console.error('查询用户失败:', err);
        return null;
    }
}

2. 给单连接添加自动重连机制(仅适合小流量场景)

如果坚持使用单连接,可以监听连接的error事件,当检测到连接断开时自动重新连接:

const mysql = require('mysql2');

let con;

function initConnection() {
    con = mysql.createConnection({
        host: 'ip',
        user: 'username',
        password: 'password',
        database: 'database_name',
    });

    con.connect(err => {
        if (err) {
            console.error('数据库连接失败,1秒后重试:', err);
            setTimeout(initConnection, 1000);
            return;
        }
        console.log('数据库连接成功');
    });

    // 监听连接错误,断开时自动重连
    con.on('error', err => {
        console.error('连接异常:', err);
        if (err.code === 'PROTOCOL_CONNECTION_LOST') {
            initConnection();
        } else {
            throw err;
        }
    });
}

initConnection();

注意:这种方式需要额外处理重连过程中的查询排队问题,否则重连期间的查询会直接失败,因此仅适合低并发的简单场景。

3. 调整MySQL服务器超时参数(治标不治本,不推荐)

可以修改MySQL配置文件中的wait_timeout和interactive_timeout参数,将超时时间延长(例如设置为24小时),但这只是推迟问题出现的时间,无法彻底解决,还会占用更多服务器连接资源,不建议采用。


额外建议

你的报错本质是未处理查询失败的情况,建议在所有数据库查询逻辑中添加错误捕获(如try/catch),避免因单个查询失败导致整个机器人崩溃。

内容的提问来源于stack exchange,提问作者Idoski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 19:31:16