129 lines
3.7 KiB
JavaScript
129 lines
3.7 KiB
JavaScript
const mysql = require('mysql2/promise');
|
||
|
||
// 数据库配置
|
||
const dbConfig = {
|
||
// host: process.env.DB_HOST || '114.55.111.44',
|
||
// user: process.env.DB_USER || 'maov2',
|
||
// password: process.env.DB_PASSWORD || '5fYhw8z6T62b7heS',
|
||
// database: process.env.DB_NAME || 'maov2',
|
||
host: '114.55.111.44',
|
||
user: 'test_mao',
|
||
password: 'nK2mPbWriBp25BRd',
|
||
database: 'test_mao',
|
||
charset: 'utf8mb4',
|
||
dateStrings: true,
|
||
// 连接池配置
|
||
connectionLimit: 20, // 连接池最大连接数
|
||
queueLimit: 0, // 排队等待连接的最大数量,0表示无限制
|
||
// 确保参数正确处理
|
||
supportBigNumbers: true,
|
||
bigNumberStrings: false
|
||
};
|
||
|
||
// 创建数据库连接池
|
||
let pool;
|
||
|
||
/**
|
||
* 初始化数据库连接池
|
||
* @returns {Promise<mysql.Pool>} 数据库连接池
|
||
*/
|
||
async function initDB() {
|
||
if (!pool) {
|
||
try {
|
||
pool = mysql.createPool(dbConfig);
|
||
|
||
// 添加连接池事件监听
|
||
pool.on('connection', function (connection) {
|
||
console.log('新的数据库连接建立:', connection.threadId);
|
||
});
|
||
pool.on('error', function (err) {
|
||
console.error('数据库连接池错误:', err);
|
||
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
|
||
console.log('数据库连接丢失,尝试重新连接...');
|
||
} else if (err.code === 'ECONNRESET') {
|
||
console.log('数据库连接被重置,尝试重新连接...');
|
||
} else if (err.code === 'ETIMEDOUT') {
|
||
console.log('数据库连接超时,尝试重新连接...');
|
||
}
|
||
});
|
||
|
||
// 测试连接
|
||
const connection = await pool.getConnection();
|
||
console.log('数据库连接池初始化成功');
|
||
connection.release();
|
||
|
||
} catch (error) {
|
||
console.error('数据库连接池初始化失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
return pool;
|
||
}
|
||
|
||
/**
|
||
* 获取数据库连接池
|
||
* @returns {mysql.Pool} 数据库连接池
|
||
*/
|
||
function getDB() {
|
||
if (!pool) {
|
||
throw new Error('数据库连接池未初始化,请先调用 initDB()');
|
||
}
|
||
return pool;
|
||
}
|
||
|
||
/**
|
||
* 执行数据库查询(带重试机制)
|
||
* @param {string} sql SQL查询语句
|
||
* @param {Array} params 查询参数
|
||
* @param {number} retries 重试次数
|
||
* @returns {Promise<Array>} 查询结果
|
||
*/
|
||
async function executeQuery(sql, params = [], retries = 3) {
|
||
for (let i = 0; i < retries; i++) {
|
||
try {
|
||
const connection = await pool.getConnection();
|
||
try {
|
||
const [results] = await connection.execute(sql, params);
|
||
connection.release();
|
||
return results;
|
||
} catch (error) {
|
||
connection.release();
|
||
throw error;
|
||
}
|
||
} catch (error) {
|
||
console.error(`数据库查询失败 (尝试 ${i + 1}/${retries}):`, error.message);
|
||
|
||
if (i === retries - 1) {
|
||
throw error;
|
||
}
|
||
|
||
// 如果是连接相关错误,等待后重试
|
||
if (error.code === 'PROTOCOL_CONNECTION_LOST' ||
|
||
error.code === 'ECONNRESET' ||
|
||
error.code === 'ETIMEDOUT') {
|
||
console.log(`等待 ${(i + 1) * 1000}ms 后重试...`);
|
||
await new Promise(resolve => setTimeout(resolve, (i + 1) * 1000));
|
||
} else {
|
||
throw error;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 关闭数据库连接池
|
||
*/
|
||
async function closeDB() {
|
||
if (pool) {
|
||
await pool.end();
|
||
pool = null;
|
||
console.log('数据库连接池已关闭');
|
||
}
|
||
}
|
||
|
||
module.exports = {
|
||
initDB,
|
||
getDB,
|
||
closeDB,
|
||
dbConfig
|
||
}; |