我有几个模块可以从数据库中提取数据并将它们存储在本地内存中。然后,我有了一些功能,可以在不同页面需要它们时从对象中提取数据。它工作得很好,除了每天一次或两次在我的登台服务器上,对象是空的,我必须重新启动服务器以再次填充数据。
我在这里删除了一些复杂性,但这就是想法,几个小时后,道路为空,并且getRoad始终返回null;
var db = require('./db.js');
var roads = [];
db.query('select * from road', function(err, rows) {
if (err) { console.log(err); }
roads = rows;
});
module.exports.getRoad = function(id) {
if (roads[id]) {
return roads[id];
}
return null;
};
更新:
我正在添加db.js,以便您可以查看其中的内容。我也对每个日志进行了大量日志记录,因此下次失败时,我将提供更多详细信息。
var Pool = require('mysql-simple-pool');
var mysql_pool = new Pool(50, {
host: process.env.IP || '127.0.0.1',
user: 'username',
password: 'password',
database: 'database'
});
module.exports = mysql_pool;
更新:
好吧,我可能会提出一个单独的问题,但似乎唯一要中断的是对数据库的调用。因此,垃圾回收绝对不是问题。似乎有些错误,或者是mysql-simple-pool之类的东西。如果有人知道为什么mysql-simple-pool将在12个小时左右后停止响应,我将不胜感激:)。
最佳答案
从这个简化的代码示例中,我可以看到的唯一情况是,您的db.query
回调函数最终在数小时后再次被调用,这表明db.js中存在某种问题。
您是否已检查日志中的console.log(err)
输出?roads
中的数据不会被垃圾收集,因为如果您要调用getRoad
,则必须有对模块的可访问引用;并且如果该模块本身有可访问的引用,则您的本地人将没有资格领取。
另外,还有一些技巧:在回调函数中,实际上应该仅在没有错误的情况下采取措施。换句话说,添加一个else
。
db.query('select * from road', function(err, rows) {
if (err) { console.log(err); }
else roads = rows;
});
如果确实确实再次调用了回调(带有错误),则可以防止
roads
被任何内容覆盖。最后,我强烈建议使
getRoad
异步。如果您需要转向更具扩展性的缓存解决方案(例如redis / memcahed / etc),这将在将来为您提供灵活性。就像是:module.exports.getRoad = function(id, cb) {
if (roads[id]) { // this part could later be easily substituted for some
cb(null, roads[id]); // other caching mechanism.
} else {
db.query('select * from road where id=?', [id], function(err, row) {
if (err) cb(err);
else if (row.length == 0) cb('Not found');
else {
roads[id] = row[0];
cb(null, row[0]);
}
});
}
};