如何在 Node JS 中执行/中止长时间运行的任务?
问题:如何在 Node JS 中执行/中止长时间运行的任务? 具有 Mongo DB 的 NodeJS 服务器 - 一个功能将从 DB 生成报告 JSON 文件,这可能需要一段时间(60 秒以上 - 必须处理数十万个条目)。 我们希望将其作为后台任务运行。如果用户决定更改参数并重新构建它,我们需要能够启动报表构建过程、监控它并中止它。 节点最简单的方法是什么?不想进入单独的工作服务器处理作业、消息
问题:如何在 Node JS 中执行/中止长时间运行的任务?
具有 Mongo DB 的 NodeJS 服务器 - 一个功能将从 DB 生成报告 JSON 文件,这可能需要一段时间(60 秒以上 - 必须处理数十万个条目)。
我们希望将其作为后台任务运行。如果用户决定更改参数并重新构建它,我们需要能够启动报表构建过程、监控它并中止它。
节点最简单的方法是什么?不想进入单独的工作服务器处理作业、消息队列等领域——我们需要将其保持在同一个盒子上并且实现相当简单。
1)以异步方法启动构建,并返回给用户,socket.io报告进度?
- 为构建脚本分离一个子进程?
3)使用类似https://www.npmjs.com/package/webworker-threads的东西?
通过我研究过的几种方法,我陷入了相同的两个领域;
- 如何监控进度? 2)如果用户重新提交数据,如何中止现有的构建过程?
任何指针将不胜感激......
解答
最好的办法是将此任务与您的主应用程序分开。也就是说,在后台运行它很容易。要在后台运行它并在没有消息队列等的情况下进行监控,最简单的方法是child_process
。
1.您可以在用户调用的端点(或url)上启动spawn
作业。
2.接下来设置一个socket
返回子进程的实时监控
- 添加另一个端点以停止作业,由
1.
返回唯一的 id(或不,取决于您的并发需求)
一些编码思路:
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中使用它。添加一条路线来监控作业并每秒调用一次。工作结束时不要忘记释放内存。
您可能想查看这个库,它将帮助您管理跨微服务的多处理。
更多推荐
所有评论(0)