我有几个模块可以从数据库中提取数据并将它们存储在本地内存中。然后,我有了一些功能,可以在不同页面需要它们时从对象中提取数据。它工作得很好,除了每天一次或两次在我的登台服务器上,对象是空的,我必须重新启动服务器以再次填充数据。

我在这里删除了一些复杂性,但这就是想法,几个小时后,道路为空,并且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]);
            }
        });
    }
};

10-05 19:32