我为一个节点应用程序运行了约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();
}
}
});
};
如您所见,我创建了连接,一旦将其释放以供使用,便再次销毁它。我现在面临的问题是,当我的CCU超过3000-5000时,连接会保持打开状态并保持打开状态。是否有更好的方法在多个节点服务器上实现该系统?
因为我大约有100台服务器,所以不能使用池并保持连接打开。而且我无法始终保持100个空闲连接打开。
答案 0 :(得分:1)
您正在使用连接池,其目的是创建到数据库的开放连接的“池”(保持开放状态并可以在以后的查询中重用)。池的默认连接大小为10。因此,在您的世界中,似乎每个服务器的池将有10个打开的连接。
要使用较少的并发连接,可以完全停止使用缓冲池(这样一台空闲服务器将不保存任何打开的连接),或者可以在创建缓冲池时使用connectionLimit
option减小连接缓冲池的大小。
要允许连接池正常运行,请使用connection.release()
,而不要使用connection.destroy()
。
如果您将池设置为较小和/或使用connection.destroy()
,但仍根据客户端数量看到连接继续攀升,则可能存在连接泄漏-代码中的某些位置不能正确清除不再使用的连接。
您可以将调试添加到连接池中,以监听和记录acquire
, connection
, enqueue
and release
events on the pool,以更好地了解连接池中正在发生的事情。
这里是对debugging a connection leak的讨论。