我遇到麻烦,我的节点应用程序突然开始耗费大量CPU。我怀疑下面的功能会以某种方式卡住..
Client.prototype.countActiveChatsRedis = function (userID, agentID, obj, callback) {
var count = 0;
pub.keys("widgetActive:" + userID + ":*", function(err, key) {
if(err !== null) {
console.log("Redis error..... --> " + err);
callback(count, obj);
}
if(key && key.length > 0) {
pub.mget(key, function(err, data) {
if(data) {
for(var i = 0; i < data.length;i++) {
if(data[i]) {
var arr = data[i].split(",");
if(arr[2] == agentID) {
if (Number(arr[3]) > 0) {
count++;
}
}
}
}
callback(count, obj);
}
});
} else {
callback(count, obj);
}
});
}
任何想法可能是什么问题?是否可以避免发送回调?
此功能每秒运行约50次。
答案 0 :(得分:3)
在生产环境中使用KEYS是不好的做法。引用Redis大师的话:
警告:将KEYS视为仅应在其中使用的命令 生产环境非常谨慎。它可能会破坏性能 当它针对大型数据库执行时。这个命令是有意的 用于调试和特殊操作,例如更改密钥空间 布局。不要在常规应用程序代码中使用KEYS。如果你是 想一想在键空间的子集中查找键的方法,请考虑 使用SCAN或设置。
每当您添加带有此前缀的密钥时,只需将其添加到名为&#34; widgetActive&#34;的集合中。用户的ID或您需要的任何其他数据。 如果您需要为每个条目保存一些数据,也可以使用HASH。
答案 1 :(得分:0)
你应该总是返回你的回调,以确保你的函数正确终止并将控件返回给调用上下文:
Client.prototype.countActiveChatsRedis = function (userID, agentID, obj, callback) {
var count = 0;
pub.keys("widgetActive:" + userID + ":*", function(err, key) {
if(err !== null) {
console.log("Redis error..... --> " + err);
return callback(count, obj);
}
if(key && key.length > 0) {
pub.mget(key, function(err, data) {
if(data) {
for(var i = 0; i < data.length;i++) {
if(data[i]) {
var arr = data[i].split(",");
if(arr[2] == agentID) {
if (Number(arr[3]) > 0) {
count++;
}
}
}
}
return callback(count, obj);
}
});
} else {
return callback(count, obj);
}
});
}
答案 2 :(得分:0)
它被卡住了,因为在没有数据的情况下,没有调用回调。
pub.mget(key, function(err, data) {
if(data) {
for(var i = 0; i < data.length;i++) {
if(data[i]) {
var arr = data[i].split(",");
if(arr[2] == agentID) {
if (Number(arr[3]) > 0) {
count++;
}
}
}
}
// callback(count, obj); // <==== move this callback outside of if (data)
}
callback(count, obj); // this ensures that callback always gets called
});