NodeJs App - 重复作业 - 单个或多个子进程?

时间:2016-07-07 01:56:47

标签: node.js child-process

我目前正在开发一个带有REST API的节点js应用程序,该应用程序公开来自mongo db的数据。

应用程序需要通过调用外部服务每5分钟更新一些数据(可能需要一分钟以上才能获得新数据)。

我决定将此任务隔离到child_process中,但我不确定在这个子进程中应该放置什么:

  • 仅执行要执行的功能。时间表由主要流程管理。
  • 拥有一个独立的进程,每5分钟自动刷新一次数据,并在每次刷新完成后向主进程发送一条消息。

我真的不知道每5分钟启动一个新的子进程是否需要很高的成本,或者我是否应该只使用一个长时间运行的子进程,或者我是否过度思考问题^^

编辑 - 更新任务

更新任务可能需要一分多钟,但它包含许多较小的任务(从许多外部提供商收集信息)而不是异步运行许多我甚至不需要子进程吗?

谢谢!

3 个答案:

答案 0 :(得分:1)

Node.js有一个能够处理异步调用的事件驱动架构,因此它与典型的C ++程序不同,你可以使用多线程/流程架构。

对于你的用例,我想也许你可以利用setInterval重复执行一个操作,你可以通过使用某种promises框架来定义更微小的异步调用像bluebirdJS

有关详细信息,请参阅:

setInterval https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval

  

<强>的setInterval()

     

重复调用函数或执行带有修复的代码片段   每次通话之间的时间延迟。返回intervalID。

示例代码:

setInterval(function() {
    console.log("I was executed"); 
}, MILLISECONDS_IN_FIVE_MINUTE);

承诺http://bluebirdjs.com/docs/features.html

示例代码:

new Promise(function(resolve, reject) {
  updateExternalService(data)
    .then(function(response) {
        return this.parseExtResp(response);  
    })
    .then(function(parsedResp) {
        return this.refreshData(parsedResp);
    })
    .then(function(returnCode) {
        console.log("yay updated external data source and refreshed");
        return resolve();
    })
    .catch(function(error) {
        // Handle error
        console.log("oops something went wrong ->" + error.message);
        return reject();
    });
  }

答案 1 :(得分:1)

这取决于您的应用与自动刷新任务之间的凝聚力。

如果自动刷新任务可以独立运行,无需与您的应用进行交互,那么最好将您的任务作为新流程启动。直接使用child_process不是一个好主意,spawn / monitor / respawn子进程很棘手,你可以使用crontab或pm2来管理它。

如果自动刷新任务取决于您的应用,您可以直接使用child_process,向其发送消息以进行计划。但首先尝试打破这种依赖性,这将简化您的应用程序,易于部署和单独维护。子进程是长时间运行的,或者在一台计算机上运行数百个这样的任务之前,一次性不是问题。

答案 2 :(得分:1)

只要您使用异步请求,从外部服务获取数据所需的总时钟时间无关紧要。重要的是你在这方面使用了多少CPU。如果大部分时间都在等待外部服务响应或发送数据,那么你的node.js服务器大部分时间都处于空闲状态,你可能不需要子进程。

因为node.js是异步的,所以它可以很高兴地拥有许多正在等待响应的“飞行中”的开放请求,并且只占用很少的系统资源。

因为node.js是单线程的,所以CPU使用率通常会驱动对子进程的需求。如果从外部服务获得响应需要5分钟,但只需要50ms的实际CPU时间来处理该请求并对其执行某些操作,那么您可能不需要子进程。

如果是我,我会将与外部服务进行通信的代码分离到自己的模块中,但在实际有一些数据需要进行此类更改之前,我不会添加子进程的复杂性

  

我真的不知道开始一个新孩子的成本是否很高   每5分钟处理一次,或者我应该只使用一次长时间运行   儿童过程或者我是否在思考问题

启动新的子进程肯定会有一些成本。这并不是很大,但是如果你每5分钟做一次并且不需要大量的内存,那么最好只启动一次子进程,让它管理与之通信的时间表。外部服务完全依赖于它自己,然后它可以根据需要将结果传回给你的其他node.js进程。这使得第二个节点进程更加自包含,并且两个进程之间唯一的交互点是传达更新。这种功能和责任的分离通常被认为是一件好事。在多开发人员项目中,您可以更轻松地让不同的开发人员处理每个应用程序。