koa:mongodb/redis 活动连接数不断增加
koa: mongodb/redis active connection count ever-increasing
我正在使用中间件像这样传递我的 mongodb/redis 客户端实例:
function *middleware(next) {
// allow downstream to handle db connection error gracefully
try {
this.db = yield mongodb.apply(this);
} catch(err) {
this.db = false;
this.app.emit('error', err, this);
}
try {
this.redis = yield redis.apply(this);
} catch(err) {
this.redis = false;
this.app.emit('error', err, this);
}
yield next;
};
yield mongodb.apply(this),调用类似的东西。
// build server string
var url = 'mongodb://';
if (opts.user && opts.pass) {
url += opts.user + ':' + opts.pass + '@';
}
// basic connection url
url += opts.server + ':' + opts.port
+ '/' + opts.database + '?w=' + opts.w;
if (opts.replSet) {
url += '&replicaSet=' + opts.replSet;
}
if (opts.userdb) {
url += '&authSource=' + opts.userdb;
}
// make sure we have active connection to mongodb
return yield mongo(url);
yield redis.apply(this),调用类似的东西。
var client = redis.createClient(opts);
// prevent redis error from crashing our app
client.on('error', function(err) {
// you can log driver connection attempts here
});
// make sure we have active connection to redis
yield client.select(opts.database);
return client;
但在这种模式下,我看到与 mongodb/redis 的活动连接不断增加,最终达到限制并阻止驱动程序打开更多连接。
// for redis
# Clients
connected_clients:64
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
// for mongodb
"globalLock" : {
"totalTime" : NumberLong("858671365000"),
"currentQueue" : {
"total" : 0,
"readers" : 0,
"writers" : 0
},
"activeClients" : {
"total" : 329,
"readers" : 0,
"writers" : 0
}
},
我最好的猜测是我没有正确地重新使用客户端。有人能给我一个关于如何在 koa 上下文中正确重用 redis client/mongodb 客户端的简单示例吗?
我最好保留像上面那样捕获连接错误的能力,这样我的 node.js 应用程序就不会因为我的数据库关闭而关闭。
PS:我主要使用 yieldb
和 then-redis
,因为它们基于 promise-base api,但是使用本机驱动程序的示例也很好。
原来问题很明显。
而不是这个:
function *database() {
var client = yield mongo(this.mongo.url);
return client;
};
我应该这样做;
var client;
function *database() {
if (client) {
return client;
}
client = yield mongo(this.mongo.url);
return client;
};
缓存实例而不是创建更多实例(这反过来会打开更多连接)。
我正在使用中间件像这样传递我的 mongodb/redis 客户端实例:
function *middleware(next) {
// allow downstream to handle db connection error gracefully
try {
this.db = yield mongodb.apply(this);
} catch(err) {
this.db = false;
this.app.emit('error', err, this);
}
try {
this.redis = yield redis.apply(this);
} catch(err) {
this.redis = false;
this.app.emit('error', err, this);
}
yield next;
};
yield mongodb.apply(this),调用类似的东西。
// build server string
var url = 'mongodb://';
if (opts.user && opts.pass) {
url += opts.user + ':' + opts.pass + '@';
}
// basic connection url
url += opts.server + ':' + opts.port
+ '/' + opts.database + '?w=' + opts.w;
if (opts.replSet) {
url += '&replicaSet=' + opts.replSet;
}
if (opts.userdb) {
url += '&authSource=' + opts.userdb;
}
// make sure we have active connection to mongodb
return yield mongo(url);
yield redis.apply(this),调用类似的东西。
var client = redis.createClient(opts);
// prevent redis error from crashing our app
client.on('error', function(err) {
// you can log driver connection attempts here
});
// make sure we have active connection to redis
yield client.select(opts.database);
return client;
但在这种模式下,我看到与 mongodb/redis 的活动连接不断增加,最终达到限制并阻止驱动程序打开更多连接。
// for redis
# Clients
connected_clients:64
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
// for mongodb
"globalLock" : {
"totalTime" : NumberLong("858671365000"),
"currentQueue" : {
"total" : 0,
"readers" : 0,
"writers" : 0
},
"activeClients" : {
"total" : 329,
"readers" : 0,
"writers" : 0
}
},
我最好的猜测是我没有正确地重新使用客户端。有人能给我一个关于如何在 koa 上下文中正确重用 redis client/mongodb 客户端的简单示例吗?
我最好保留像上面那样捕获连接错误的能力,这样我的 node.js 应用程序就不会因为我的数据库关闭而关闭。
PS:我主要使用 yieldb
和 then-redis
,因为它们基于 promise-base api,但是使用本机驱动程序的示例也很好。
原来问题很明显。
而不是这个:
function *database() {
var client = yield mongo(this.mongo.url);
return client;
};
我应该这样做;
var client;
function *database() {
if (client) {
return client;
}
client = yield mongo(this.mongo.url);
return client;
};
缓存实例而不是创建更多实例(这反过来会打开更多连接)。