nds*_*dsc 7 javascript memory-leaks mongoose node.js restify
更新4:通过在函数外部实例化restify客户端(请参阅controllers/messages.js)并在每次请求后调用global.gc(),内存增长速度似乎已经降低了很多(每10秒约500KB).然而,内存使用量仍在不断增长.
Update3:发过这篇文章:https://journal.paul.querna.org/articles/2011/04/05/openssl-memory-use/
值得注意的是,我正在使用HTTPS和Restify.
更新2:将以下代码更新为当前状态.我试过用Express换掉Restify.可悲的是,这没有任何区别.似乎链条末端的api调用(restify - > mongodb - > external api)会导致所有内容保留在内存中.
更新1:我用标准的MongoDB驱动程序替换了Mongoose.内存使用似乎增长速度较慢,但泄漏仍然存在.
我一直在努力寻找这种泄漏现在几天.
我正在使用Restify和Mongoose运行API ,并且对于每个API调用,我至少进行一次MongoDB查找.我有大约1-2k用户在一天内多次点击API.
我试过了什么
那么,可能出现什么问题呢?
我只使用一个API用户完成了上述测试.这意味着Mongoose只能一遍又一遍地抓取同一个文档.与生产的不同之处在于许多不同的用户都在使用API,这意味着mongoose会获得大量不同的文档.
当我启动nodejs服务器时,内存会迅速增长到100MB-200MB.它最终稳定在500MB左右.这是否意味着它会为每个用户泄漏内存?一旦每个用户访问过API,它都会稳定下来吗?
我在下面列出了我的代码,其中概述了我的API的一般结构.我很想知道我的代码或任何其他方法是否存在严重错误,以找出导致高内存使用的原因.
码
app.js
var restify = require('restify');
var MongoClient = require('mongodb').MongoClient;
// ... setup restify server and mongodb
require('./api/message')(server, db);
Run Code Online (Sandbox Code Playgroud)
API/message.js
module.exports = function(server, db) {
// Controllers used for retrieving accounts via MongoDB and communication with an external api
var accountController = require('../controllers/accounts')(db);
var messageController = require('../controllers/messages')();
// Restify bind to put
server.put('/api/message', function(req, res, next) {
// Token from body
var token = req.body.token;
// Get account by token
accountController.getAccount(token, function(error, account) {
// Send a message using external API
messageController.sendMessage(token, account.email, function() {
res.send(201, {});
return next();
});
});
});
};
Run Code Online (Sandbox Code Playgroud)
控制器/ accounts.js
module.exports = function(db) {
// Gets account by a token
function getAccount(token, callback) {
var ObjectID = require('mongodb').ObjectID;
var collection = db.collection('accounts');
collection.findOne({
token: token
}, function(error, account) {
if (error) {
return callback(error);
}
if (account) {
return callback('', account);
}
return callback('Account not found');
});
}
};
Run Code Online (Sandbox Code Playgroud)
控制器/ messages.js
module.exports = function() {
function sendMessage(token, email, callback) {
// Get a token used for external API
getAccessToken(function() {}
// ... Setup client
// Do POST
client.post('/external_api', values, function(err, req, res, obj) {
return callback();
});
});
}
return {
sendMessage: sendMessage
};
};
Run Code Online (Sandbox Code Playgroud)
怀疑泄漏的快照
