带有Mongo DB的NodeJS服务器 - 一个功能将从数据库生成一个报告JSON文件,这可能需要一段时间(60秒以上 - 必须处理数十万个条目)。
我们希望将其作为后台任务运行。我们需要能够启动报告构建过程,监视它并在用户决定更改params并重新构建它时中止它。
节点最简单的方法是什么?并不是真的想进入处理作业,消息队列等的单独工作服务器的领域 - 我们需要将它保存在同一个盒子和相当简单的实现上。
1)以async方式启动构建,并返回给用户,socket.io报告进度?
2)为构建脚本分离子进程?
3)使用类似https://www.npmjs.com/package/webworker-threads的内容?
通过我看过的几种方法,我陷入了同样的两个方面;
1)如何监控进度? 2)如果用户重新提交数据,如何中止现有的构建过程?
任何指针都会非常感激......
答案 0 :(得分:5)
最好将此任务与主应用程序分开。也就是说,在后台运行它很容易。
要在后台运行它并监控没有消息队列等,最简单的是child_process
。
spawn
作业。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中使用它。添加路线以监控工作并每秒调用一次。不要忘记在工作结束时释放记忆。
您可能需要查看this library,它可以帮助您管理跨微服务的多处理。