关于如何使用Nodejs更新SQL缓存的问题

关于如何使用Nodejs更新SQL缓存的问题

var config = require(’./config’);
var net = require(‘net’);
var mysql_driver = require(‘mysql’);

var mysql = mysql_driver.createConnection(config.db); mysql.connect(); var cache = {}; // Build the cache var csql = “SELECT * FROM (SELECT accountID, deviceID, uniqueID FROM Device ORDER BY uniqueID DESC) sub GROUP BY uniqueID”; mysql.query(csql, function(err, rows, fields) { for (key in rows) { cache[rows[key].uniqueID] = {}; cache[rows[key].uniqueID].accountID = rows[key].accountID; cache[rows[key].uniqueID].deviceID = rows[key].deviceID; } });

运行这个udp-parse.js后,如果在运行期间,接收到缓存里没有的uniqueID,会导致udp-parse.js程序停止运行,不知道可否定期查询一下上面的代码。

var account = cache[datum.uniqueID].accountID; ^ TypeError: Cannot read property ‘accountID’ of undefined at Socket.recvMsg (/home/node/NodeJS-Server/udp-parse.js:170:54) at Socket.EventEmitter.emit (events.js:99:17) at UDP.onMessage (dgram.js:353:8) DEBUG: Program node udp-parse.js exited with code 1

DEBUG: Starting child process with ‘node udp-parse.js’

got message from 119.142.84.130:10000


8 回复

针对“关于如何使用Nodejs更新SQL缓存的问题”,我们可以设计一个方案来解决这个问题。该方案将包括如何创建一个缓存机制,并且定期从数据库中刷新缓存以确保数据的一致性和完整性。

示例代码

const mysql_driver = require('mysql');
const config = require('./config');

// 创建数据库连接
const mysql = mysql_driver.createConnection(config.db);

// 初始化缓存对象
let cache = {};

// 定义函数用于更新缓存
function updateCache() {
    return new Promise((resolve, reject) => {
        const csql = "SELECT * FROM (SELECT accountID, deviceID, uniqueID FROM Device ORDER BY uniqueID DESC) sub GROUP BY uniqueID";
        mysql.query(csql, (err, rows, fields) => {
            if (err) {
                reject(err);
                return;
            }
            // 更新缓存
            rows.forEach(row => {
                cache[row.uniqueID] = {
                    accountID: row.accountID,
                    deviceID: row.deviceID
                };
            });
            resolve(cache);
        });
    });
}

// 初始化缓存
updateCache()
    .then(() => console.log('缓存已更新'))
    .catch(err => console.error('缓存更新失败', err));

// 定期更新缓存(例如每小时)
setInterval(updateCache, 3600000); // 每小时执行一次

解释

  1. 数据库连接:首先,我们通过mysql_driver.createConnection方法创建了一个到MySQL数据库的连接。
  2. 初始化缓存:定义了一个名为cache的对象来存储从数据库获取的数据。
  3. 更新缓存:定义了updateCache函数,该函数执行SQL查询并将结果存储到cache对象中。这是一个异步操作,因此使用Promise来处理。
  4. 定期更新:通过setInterval函数,每隔一段时间(例如每小时)调用updateCache函数来刷新缓存。这有助于确保缓存中的数据是最新的。

通过这种方式,当udp-parse.js脚本运行时,即使接收到不在缓存中的uniqueID,也不会导致程序崩溃,因为缓存会定期更新,包含最新的数据。


这个属于代码结构不严谨的原因,如果没有,你可以返回一个空对象而不是定期查询将简单的事情复杂化例如这样:

var account = datum.uniqueID ? (cache[datum.uniqueID].accountID ? cache[datum.uniqueID].accountID : {}) : {};

如果不查询的话,在JS运行期间,系统新增的帐号就不能查到并写入定位数据,因为数据库表的主键有3个,所以必须查DeviceID表才能查 accountID和deviceID。

谢谢你的回复。

那你可以用下kue,npm install kue,将你上面那段代码变成一个job,设置时间定期去执行,地址:https://github.com/LearnBoost/kue

差点忘说了,至于定时可以用cron这个lib去做,https://github.com/ncb000gt/node-cron, 设置定时去执行你用kue做成的job

找个一个简单的办法:

var minutes = 1, the_interval = minutes * 60 * 1000;
setInterval(function() {
console.log("query db account every 1 min");
var csql = "SELECT * FROM (SELECT accountID, deviceID, uniqueID,smsEmail FROM Device ORDER BY uniqueID DESC) sub GROUP BY uniqueID";
mysql.query(csql, function(err, rows, fields) {
for (key in rows) {
cache[rows[key].uniqueID] = {};
cache[rows[key].uniqueID].accountID = rows[key].accountID;
cache[rows[key].uniqueID].deviceID = rows[key].deviceID;
cache[rows[key].uniqueID].smsEmail = rows[key].smsEmail;
}
});

}, the_interval);

为了确保在udp-parse.js运行期间能够及时更新SQL缓存,并且避免在缓存中找不到uniqueID时导致程序停止运行,可以采用定期查询数据库的方式来保持缓存是最新的。这里提供一个解决方案,包括设置定时器定期从数据库获取最新的数据来更新缓存。

示例代码

var config = require('./config');
var net = require('net');
var mysql_driver = require('mysql');

// 创建数据库连接
var mysql = mysql_driver.createConnection(config.db);

// 初始化缓存
var cache = {};

// 定期更新缓存函数
function updateCache() {
    var csql = "SELECT * FROM (SELECT accountID, deviceID, uniqueID FROM Device ORDER BY uniqueID DESC) sub GROUP BY uniqueID";
    mysql.query(csql, function(err, rows, fields) {
        if (err) throw err;

        // 清空并重新填充缓存
        cache = {};
        for (let row of rows) {
            cache[row.uniqueID] = {
                accountID: row.accountID,
                deviceID: row.deviceID
            };
        }
    });
}

// 初始加载缓存
updateCache();

// 设置每分钟更新一次缓存
setInterval(updateCache, 60000);

// 监听UDP信息
var server = net.createServer(function(socket) {
    socket.on('data', function(datum) {
        var uniqueID = datum.uniqueID;
        
        // 检查缓存中是否存在uniqueID
        if (cache[uniqueID]) {
            var account = cache[uniqueID].accountID;
            console.log(`Processing data for ${account}`);
        } else {
            console.log(`No data found for uniqueID: ${uniqueID}`);
        }
    });

    socket.on('end', function() {
        socket.end();
    });
});

server.listen(12345); // 假设监听端口为12345

解释

  • 定时更新:使用setInterval函数每分钟调用一次updateCache函数,确保缓存中的数据是最新的。
  • 错误处理:在执行数据库查询时添加了错误处理机制,以防查询失败导致程序崩溃。
  • 缓存管理:每次更新缓存时先清空原有的缓存,然后重新填充新的数据。

这样,即使在运行期间接收到新的或未出现在缓存中的uniqueID,程序也不会因为找不到对应的值而崩溃,而是通过日志提示信息的缺失。

回到顶部