试图了解Node和Heroku上的工作者与线程。当您在Node.js中调用exec
时会发生什么?
相信它在一个单独的线程上运行,并且不会阻塞主事件循环,这是正确的吗?
require('child_process').exec(cmd, function (err, stdout, stderr) {
// ... do stuff
});
如果在Heroku上,将其转移到单独的工人身上有好处吗?例如
- 如果计算密集,child_process会减慢主应用程序的速度吗
- 工作者dynos有自己的记忆限制吗
- 如果在工作人员中,一个未捕获的错误(但愿不会)不会导致主应用程序崩溃吗
在Node中,子进程是CPU上真正独立的进程,它是父进程(Node.js脚本)的子进程。本文在这里对此进行了更深入的解释:http://www.graemeboy.com/node-child-processes
这在Heroku上意味着,如果您使用child_process
生成一个新的子进程,您的Heroku dyno实际上将能够完成"更多"的总CPU工作,因为它将(很可能)在单独的物理CPU上运行您的子进程代码(然而,这非常依赖于应用程序中的许多因素)。
然而,这可能是一个问题,因为每个Heroku dyno只有有限的CPU和RAM资源。
因此,例如,如果您的Dyno代码(web位,而不是单独的Heroku工作程序)正在做CPU密集型的工作,并且大量使用child_process
,那么您将耗尽所有的CPU资源,并且您的代码将开始在Node中阻塞/挂起。
一个更好的想法(尽管在Heroku上稍微贵一点)是将所有工作程序/异步代码放在一个单独的工作程序dyno中,并专门用于处理CPU密集型的东西。这可以确保您的主要网络dynos始终快速响应,尽可能多。
我个人喜欢使用像亚马逊SQS这样的排队服务来处理我的网络dynos和我的工作人员dynos之间的数据传递,因为它速度极快,价格低廉,但你有很多选择。
你创建的每个dyno(web dyno和worker dyno)都有自己的资源,所以每个dyno都有自己设定的CPU和RAM。可用dynos的类型及其资源限制,并在此处解释:https://devcenter.heroku.com/articles/dyno-types
关于错误处理,如果您没有捕捉到异常,那么很难说会发生什么。然而,你的整个Node应用程序很可能会崩溃(然后Heroku会重新启动它)。这实际上取决于您对各种事物的具体实现=/