节点微服务不断查询mysql db

时间:2018-03-08 07:44:46

标签: mysql node.js synchronization

我是Node.js的新手,我正在尝试创建一个简单的微服务,它不断轮询数据库中的记录,对这些记录执行异步作业,并在作业完成后更新数据库中这些记录的状态。完成。

基本上这是我的内部查询和循环:

const con = mysql.createConnection({
  host: 'localhost',
  user: 'user',
  password: 'password',
  database: 'sitepoint'
});

con.query('SELECT * FROM records where flag = 0', (err,rows) => {
  if(err) throw err;
  rows.forEach( (row) => {
  someFunction(row, function(result,err){
     if(err) throw err;
     //Update record in db
}
});

});

这是我正在做的事情的粗略概念,我的问题是我想在设定的时间间隔内连续这样做,比如说每1分钟但我确实希望在处理完最后一行后计算间隔我的查询。换句话说,我想阻塞,直到处理完所有获取的行。我在node.js中有哪些选择?

1 个答案:

答案 0 :(得分:1)

我建议使用在大量服务器中使用的简单模式,其中作业排队自己,您可以获得间隔每次都可以更改并且作业完成之间的间隔得到修复的好处而不是作业开始之间的间隔被修复。

function getQueryInterval() {
    // Could read from a DB, Redis, etc.
    return 60000;
}

function processRow(row) {
    /* Do some good stuff with the row. */
    return Promise.resolve('OK');
}

function runQuery() {
    console.log(new Date().toISOString(), 'runQuery: Running..');

    // Return a master promise, this will only resolve when everything is complete. 
    // However as soon as an error is encountered it will reject.
    return new Promise((resolve, reject) => {
        let processPromises = [];
        con.query('SELECT * FROM records where flag = 0', (err,rows) => {
            if(err) reject(err);
            rows.forEach( (row) => {
                someFunction(row, function(result,err) {
                    if(err) reject(err);
                    //Update record in db
                    processPromises.push(processRow(row));
                });
            });

            // Only resolve when all records are processed.
            Promise.all(processPromises).then((result) => { 
                resolve(result);
            }).catch ((err) => { 
                reject(err) 
            });
        });
    })
}

async function runQueryAndQueueNext() {

  try
  {
      await runQuery();
  }
  catch (err) {
      console.error(new Date().toISOString(), 'runQueryAndQueueNext: Error occurred: ', err);
  }

  console.log(new Date().toISOString(), 'runQueryAndQueueNext: Query complete, queuing next in ' + getQueryInterval() + ' ms');
    setTimeout(runQueryAndQueueNext, getQueryInterval())
}


runQueryAndQueueNext();