我有几个模块从数据库中提取数据并将它们存储在本地内存中。然后,我有一些函数可以在不同页面需要时从对象中提取数据。它运行良好,除了我的登台服务器上每天一次或两次对象为空,我必须重新启动到服务器以再次填充数据。
我已经删除了一些复杂性,但这是一个想法,几个小时后,道路为空,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个小时后停止响应,我会很感激:)。
答案 0 :(得分:1)
从这个简化的代码示例中,我能看到的唯一场景是你的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]);
}
});
}
};