如何在Node JS中执行/中止长时间运行的任务?

时间:2015-04-27 13:13:21

标签: node.js multithreading mongodb child-process long-running-processes

带有Mongo DB的NodeJS服务器 - 一个功能将从数据库生成一个报告JSON文件,这可能需要一段时间(60秒以上 - 必须处理数十万个条目)。

我们希望将其作为后台任务运行。我们需要能够启动报告构建过程,监视它并在用户决定更改params并重新构建它时中止它。

节点最简单的方法是什么?并不是真的想进入处理作业,消息队列等的单独工作服务器的领域 - 我们需要将它保存在同一个盒子和相当简单的实现上。

1)以async方式启动构建,并返回给用户,socket.io报告进度?

2)为构建脚本分离子进程?

3)使用类似https://www.npmjs.com/package/webworker-threads的内容?

通过我看过的几种方法,我陷入了同样的两个方面;

1)如何监控进度? 2)如果用户重新提交数据,如何中止现有的构建过程?

任何指针都会非常感激......

1 个答案:

答案 0 :(得分:5)

最好将此任务与主应用程序分开。也就是说,在后台运行它很容易。 要在后台运行它并监控没有消息队列等,最简单的是child_process

  1. 您可以在用户呼叫的端点(或网址)上启动spawn作业。
  2. 接下来,设置socket以返回子进程的实时监控
  3. 添加另一个端点以停止作业,1.返回唯一ID(或不,取决于您的并发需求)
  4. 一些编码想法:

    var spawn = require('child_process').spawn
    
    var job = null //keeping the job in memory to kill it
    
    app.get('/save', function(req, res) {
    
        if(job && job.pid)
            return res.status(500).send('Job is already running').end()
    
        job = spawn('node', ['/path/to/save/job.js'], 
        {
            detached: false, //if not detached and your main process dies, the child will be killed too
            stdio: [process.stdin, process.stdout, process.stderr] //those can be file streams for logs or wathever
        })
    
        job.on('close', function(code) { 
            job = null 
            //send socket informations about the job ending
        })
    
        return res.status(201) //created
    })
    
    app.get('/stop', function(req, res) {
        if(!job || !job.pid)
            return res.status(404).end()
    
        job.kill('SIGTERM')
        //or process.kill(job.pid, 'SIGTERM')
        job = null
        return res.status(200).end()
    })
    
    app.get('/isAlive', function(req, res) {
        try {
            job.kill(0)
            return res.status(200).end()
        } catch(e) { return res.status(500).send(e).end() }
    })
    

    要监控您可以使用pidusage的子进程,我们会在PM2中使用它。添加路线以监控工作并每秒调用一次。不要忘记在工作结束时释放记忆。

    您可能需要查看this library,它可以帮助您管理跨微服务的多处理。