【问题标题】:Node js async queue and multi-threadNode js异步队列和多线程
【发布时间】:2017-08-10 04:20:18
【问题描述】:

我正在使用节点 js 构建一个应用程序,该应用程序必须接受用户的请求,读取 mongodb 并更新特定的用户数据,然后再为该特定用户接受另一个请求。我可以使用带有此代码的异步队列来做到这一点:

//Create a queue with concurrency of 1
var tasksQueue = async.queue(function (userInfo, callback) {
User.verifyAndUpdateAccount(userInfo, callback)
}, 1);

router.post('/', function (req, res, next) {
res.setHeader('Content-Type', 'application/json');
//Is required datas present?
if (!req.body.username || !req.body.password) {
return res.send(null);
}
var username = req.body.username;
var password = req.body.password;
//Verify account informations and update them
tasksQueue.push({username: username, password:password}, function (err,
updatedUser) {

if (err == 'NO_MORE_REQUESTS_ALLOW') {
    // S'il ne lui reste plus de sms
    return res.send({
        code: 400,
        message: 'NO_MORE_REQUESTS_ALLOW'
    })

} else if (err) throw err;

//**********************************************************
//  Build the response here and respond to user requests
})

问题是当我使用模块cluster.js时它不能很好地工作,因为每个线程都有自己的队列并且不关心其他线程。我希望我的应用能够像这样工作:

假设 user1 发出 2 个请求,然后 user2 发出 1 个请求。假设我有 4 个内核,我希望我的第一个线程开始处理 user1 的第一个请求,并且所有线程在处理他的第二个请求之前等待 user1 第一个请求已被处理。但是其他线程必须能够在处理user1第一个请求之前处理user2请求,因为1个请求只更新mongodb中单个用户的数据,不会影响其他人,所以我们不需要等待。

【问题讨论】:

  • 这段代码没有意义。为什么你根本不做 User.find({ username, password }) 并且没有返回结果然后组合不正确?因为这有点简单,我们在非常大的系统中如何做到这一点,我们可能这样做是因为只有一个调用,而不是你试图处理的几个调用。
  • 哦...你是对的,谢谢。我会优化这段代码
  • 嗯...我已经更新了演示代码。事实上,我使用 bcrypt 对密码进行哈希处理,因此您看到的第二次调用(用于比较密码)没有对数据库进行任何调用。

标签: node.js multithreading mongodb


【解决方案1】:

也许您可以优化代码以使响应处理足够快。但是如果你确实需要一种非阻塞方式来进行繁重的计算,你可以试试'napajs',它是由微软发布的,它可以与 Node.js 一起使用,在同一进程中启用多线程 JavaScript 场景。这是一个quick introduction 供您参考。

您的代码将如下所示:

var napa = require('napajs');

// One-time setup. 
// You can change number of workers per your requirement. 
var zone = napa.zone.create('response-builders', { workers: 4 });

function serveRequest() {
    var request = null; 

    // Get request from queue.
    // ...

    zone.execute(() => {
        // Build the response here
        return response;
    }, [request]).then((result) => {
        // respond to user
        console.log(result.value);
    });
}

【讨论】:

  • 感谢您的回答,但我设法通过许多技巧解决了我的问题,例如在增量后验证数据并在某些条件下更新。
猜你喜欢
  • 2013-09-10
  • 2013-10-03
  • 1970-01-01
  • 1970-01-01
  • 2017-11-15
  • 2010-10-27
  • 1970-01-01
  • 2020-12-05
  • 1970-01-01
相关资源
最近更新 更多