我正在为我的一个节点应用程序运行大约100台服务器。每个都允许用户登录。每个服务器当前都有如下设置:
mysql.createPool({
port: xx,
connectionLimit: 20,
host: "xxx",
user: "xxx",
password: "xxx",
database: "xxx",
charset: "utf8mb4"
});
我有一个调用数据库存储过程的函数:
var queries = ["test_1", "test_2"];
此函数接受如下参数:[“alex”,“password”]
this.call = function(index, data, callback) {
pool.getConnection(function(err, connection) {
if (err) {
if (connection) connection.destroy();
if (callback) callback(err);
} else {
try {
var statement = "CALL " + context.queries[index] + "(";
for (var i = 0; i < data.length; ++i) {
statement += mysql.escape(data[i]) + (i<data.length-1?",":"");
}
statement += ")";
connection.query({
sql: statement,
timeout: 4000
}, function(error, response, fields) {
connection.destroy();
if (callback) callback(error, response, fields);
});
} catch (e) {
connection.destroy();
}
}
});
};
如您所见,我创建了连接,然后在它被用来释放供使用时再次销毁它。我现在面临的问题是,当我有超过3000-5000个ccu时,连接会一直打开并保持打开状态。有没有更好的方法跨多个节点服务器实现这个系统?
使用池并保持连接打开不是一个选项,因为我有大约100台服务器。我不能一直保持100个空闲连接。
1条答案
按热度按时间hvvq6cgz1#
您使用的是连接池,其目的是创建一个数据库的开放连接的“池”(保持开放,可以在将来的查询中重用)。池的默认连接大小为10。因此,在您的世界中,似乎每个服务器的池都有10个打开的连接。
要使用更少的并发连接,您可以完全停止使用池(这样空闲服务器将不会保留任何打开的连接),或者使用
connectionLimit
创建池时的选项。为了让连接池正常工作,可以使用
connection.release()
,不是connection.destroy()
.如果您将游泳池设置为较小和/或正在使用
connection.destroy()
您仍然会看到连接继续攀升,这取决于客户端的数量,然后您可能会出现连接泄漏-代码中的某个地方没有正确清理不再使用的连接。您可以将调试添加到连接池以侦听和记录
acquire
,connection
,enqueue
以及release
事件来更好地了解连接池上发生了什么。这里有一个关于调试连接泄漏的讨论。