inint
This commit is contained in:
46
module/server/mysql/gameDB.js
Normal file
46
module/server/mysql/gameDB.js
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* 游戏区服动态数据库连接工具
|
||||
*
|
||||
* 游戏每个区服对应独立的数据库 mir_actor_s{serverId}
|
||||
* 该模块根据 serverId 动态创建连接池(带缓存,同一区服复用连接)
|
||||
*
|
||||
* 使用示例:
|
||||
* import getGameDB from '../mysql/gameDB.js'
|
||||
* const db = getGameDB(1)
|
||||
* const [rows] = await db.query('SELECT ...')
|
||||
*/
|
||||
|
||||
import mysql from 'mysql2'
|
||||
import config from '../config/index.js'
|
||||
import * as log4js from '../log4js.js'
|
||||
|
||||
// 连接池缓存,避免对同一区服重复创建
|
||||
const poolCache = new Map()
|
||||
|
||||
/**
|
||||
* 获取指定区服的 MySQL 连接池(Promise 包装)
|
||||
* @param {number} serverId 区服 ID
|
||||
* @returns {import('mysql2/promise').Pool}
|
||||
*/
|
||||
export default function getGameDB(serverId) {
|
||||
const dbName = `mir_actor_s${serverId}`
|
||||
if (poolCache.has(dbName)) return poolCache.get(dbName)
|
||||
|
||||
const pool = mysql.createPool({
|
||||
host: config.game.dbHost || config.mysql.host,
|
||||
port: config.game.dbPort || config.mysql.port,
|
||||
user: config.game.dbUser || config.mysql.user,
|
||||
password: config.game.dbPassword || config.mysql.password,
|
||||
database: dbName,
|
||||
connectionLimit: 5,
|
||||
waitForConnections: true,
|
||||
})
|
||||
|
||||
pool.on('error', (err) => {
|
||||
log4js.mysql.error(`[${dbName}] 连接池错误:`, err.message)
|
||||
})
|
||||
|
||||
const promisePool = pool.promise()
|
||||
poolCache.set(dbName, promisePool)
|
||||
return promisePool
|
||||
}
|
||||
@@ -7,18 +7,29 @@ const pool = mysql.createPool({
|
||||
port: config.mysql.port,
|
||||
user: config.mysql.user,
|
||||
password: config.mysql.password,
|
||||
database: config.mysql.database,
|
||||
connectionLimit: 10,
|
||||
queryFormat: function (sql, values) {
|
||||
const opts = { sql, values }
|
||||
this._resolveNamedPlaceholders(opts)
|
||||
log4js.mysql.debug(opts.sql, opts.values)
|
||||
return mysql.format(
|
||||
opts.sql,
|
||||
opts.values,
|
||||
this.config.stringifyObjects,
|
||||
this.config.timezone
|
||||
)
|
||||
}
|
||||
// 不在启动时立即建立连接,等第一次查询时再连接
|
||||
waitForConnections: true,
|
||||
enableKeepAlive: true,
|
||||
keepAliveInitialDelay: 10000,
|
||||
});
|
||||
|
||||
export default pool.promise();
|
||||
// 监听连接错误,避免未处理的 Promise rejection 导致进程崩溃
|
||||
pool.on('connection', (connection) => {
|
||||
log4js.mysql.info(`MySQL 连接建立 [id=${connection.threadId}] ${config.mysql.host}:${config.mysql.port}`);
|
||||
});
|
||||
pool.on('error', (err) => {
|
||||
log4js.mysql.error('MySQL 连接池错误:', err.message);
|
||||
});
|
||||
|
||||
const promisePool = pool.promise();
|
||||
|
||||
// 健康检查:启动时 ping 一次数据库,失败只警告不崩溃
|
||||
promisePool.query('SELECT 1').then(() => {
|
||||
log4js.mysql.info(`MySQL 连接成功 ${config.mysql.host}:${config.mysql.port}/${config.mysql.database}`);
|
||||
}).catch((err) => {
|
||||
log4js.mysql.warn(`MySQL 连接失败(服务仍将继续运行): ${err.message}`);
|
||||
});
|
||||
|
||||
export default promisePool;
|
||||
|
||||
Reference in New Issue
Block a user