NodeJS批处理多进程-池中的子进程(或多线程)



NodeJS批处理多线程处理-池中的子进程

我知道子进程是一个进程,而不是线程。我使用了错误的语义,因为当你谈到"多线程"时,大多数人都知道你的意图是什么。所以我会把它保留在标题中。


想象一个场景,在这个场景中,您使用单个自定义函数或模块连续有多个类似且复杂的事情要做。使用所有可用的核心/线程(例如8/16)非常有意义,这就是child_process.fork()的用途。

理想情况下,您将需要多个同时工作的人员,并向一个控制器发送/从一个控制器发出回调消息。

node-cpool、fork-pool、child-pool是一些完全可以做到这一点的模块,但它们看起来很旧/未维护/不受欢迎。

有很多类似的ish模块,但这些模块似乎是最相关的。他们的共同点是有几次承诺,几乎没有主演,几乎没有分叉,也没有放弃。

通常情况下,当我无法为一项任务找到在各个方面都有意义的东西时,我会错过一种更好的方式。因此,我提出了这个问题。

如何为我的自定义模块创建一个托管的、排队的、多线程并行fork()池,用于执行一些CPU密集型工作

像TAGG和webworker线程这样的多线程模块不同,因为它们不支持完整的模块(使用二进制编译的组件)。


PS

我现在使用的是fork-pool,它似乎正是我想要的,有一些怪癖,但我不敢相信这样一个未知且不受欢迎的模块会是这里唯一可行的选择。

我建议使用Redis之类的东西作为队列。以下是使用Redis和Kue在Node中创建消息总线的教程。这将很好地扩展,并允许您有多个进程、线程,甚至机器在队列中生产和消费项目。

Web Workers标准为JavaScript定义了一种使用多个线程并并行执行比单个线程所能管理的更多工作的方式。

NodeJS有几种实现方式,包括webworker线程NPM模块。

使用fork是沿着通常更难协调的多进程路径进行的。NodeJS集群系统试图缓解这里的很多摩擦,但还远远不够理想。

我想提供一个选项,它不能完全回答您的问题,但在选择技术时有灵活性的类似情况下可能会有用。

如果将工作卸载到.NET环境(C#、F#、IronPython、PowerShell等)是可以接受的,那么您可能会对Edge.js项目感兴趣。

通过这种方式,您可以将Node用于IO密集型工作,并将计算密集型工作委托给托管在同一进程内的.NET运行时。Edge.js与.NET代码提供了高效的互操作性,允许利用.NET任务并行库和其他功能,而不会产生额外进程的开销。


无论何时制作混合应用程序,都会涉及到维护和技术成本。根据项目的优先级,仔细评估您获得的收益,并确保这些成本是值得的

Node.js不太适合执行阻塞、CPU受限的工作负载。node.js的显著设计特点是它的单线程、基于事件循环的体系结构。

Node.js应用程序通常通过将处理委托给外部进程或服务来处理CPU绑定的工作负载。这涉及到跨越进程边界并导致额外的延迟。(更多)

在没有充分理由的情况下引入复杂性是愚蠢的。如果Node.js可以自己处理任务,那么添加对.NET的依赖可能会有些过头。然而,有许多任务可能是有价值的。成为一名优秀的工程师需要一些思考。

我最近遇到了由单个node.js进程创建的分叉池的问题,并提出了自己的解决方案来解决这个问题。我终于成功地将解决方案导出到了自己的npm模块中,您可以在这里查看:

https://www.npmjs.com/package/forkpool

您可以创建一个单独的池来管理所有的分叉,也可以创建多个池来管理单独的工作批次。例如,我的一个应用程序有两个池——一个用于管理与图像处理相关的分叉,另一个用于视频处理。由于视频处理比图像处理更密集,因此在8核机器上,视频处理池的大小为2,而具有图像处理的视频处理池大小为4。

我希望随着时间的推移不断改进这个模块,所以可以随时在Github存储库上提出问题或增强请求:

https://github.com/manthanhd/forkpool

最新更新