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

How to execute / abort long running tasks in Node JS?

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

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

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

1) 以异步方法启动构建,并 return 给用户,并 socket.io 报告进度?

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

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

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

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

如有指点,将不胜感激...

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

  1. 您可以在用户调用的端点(或 url)上启动 spawn 作业。
  2. 接下来,设置一个 socket 到 return 子进程的实时监控
  3. 添加另一个端点以停止作业,具有由 1. 编辑的唯一 ID return(或不编辑,取决于您的并发需求)

一些编码思路:

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, we use it in PM2。添加一个路由来监控一个作业并每秒调用一次。不要忘记在作业结束时释放内存。


您可能想要查看 this library,这将帮助您管理跨微服务的多重处理。