症状
- 数据库查询超时
- 连接池耗尽
- 应用启动时数据库连接失败
- 间歇性连接断开
可能的原因
- 数据库服务器不可用
- 连接池配置不当
- 网络问题
- 认证失败
- 连接泄漏
解决方案
1. 正确配置连接池
步骤:
- 根据应用需求和数据库服务器能力设置连接池大小
- 配置连接超时和最大生命周期
- 启用连接验证
代码示例:
// Node.js + MySQL连接池示例
const mysql = require('mysql2');
const pool = mysql.createPool({
host: 'localhost',
user: 'user',
password: 'password',
database: 'db',
connectionLimit: 10,
queueLimit: 0,
waitForConnections: true,
connectTimeout: 10000,
acquireTimeout: 10000,
idleTimeout: 60000,
});
说明:
连接池配置不当可能导致连接不足或资源浪费。正确配置连接池可以提高应用性能和稳定性。
2. 实现连接重试机制
步骤:
- 捕获连接错误
- 实现指数退避重试策略
- 设置最大重试次数和超时时间
代码示例:
async function connectWithRetry() {
let retries = 5;
while (retries) {
try {
await db.connect();
console.log('Database connected');
return;
} catch (err) {
console.error('Database connection failed, retrying...', err);
retries -= 1;
// 等待时间随重试次数增加
await new Promise(resolve => setTimeout(resolve, 1000 * (5 - retries)));
}
}
throw new Error('Could not connect to database');
}
说明:
网络问题或数据库维护可能导致临时连接失败。实现重试机制可以提高应用的弹性。
3. 正确关闭连接
步骤:
- 在操作完成后释放连接
- 使用try-finally确保连接总是被释放
- 实现连接泄漏检测
代码示例:
// 使用连接池获取连接并确保释放
async function query(sql, params) {
let conn;
try {
conn = await pool.getConnection();
return await conn.query(sql, params);
} finally {
if (conn) conn.release();
}
}
说明:
未正确释放的连接会导致连接池耗尽。确保在所有情况下都释放连接可以避免连接泄漏。
4. 监控数据库连接
步骤:
- 实现健康检查接口
- 监控连接池指标
- 设置告警阈值
- 记录连接相关的错误和性能指标
代码示例:
// 简单的数据库健康检查
app.get('/health/db', async (req, res) => {
try {
const start = Date.now();
await db.query('SELECT 1');
const duration = Date.now() - start;
res.json({
status: 'up',
responseTime: duration,
connections: {
active: pool.activeConnections(),
idle: pool.idleConnections(),
total: pool.totalConnections()
}
});
} catch (err) {
res.status(500).json({
status: 'down',
error: err.message
});
}
});
说明:
监控数据库连接可以帮助及早发现问题,并提供诊断信息。健康检查接口可以集成到监控系统中。
标签
数据库连接性能运行时