TL; DR
是否可能有两个不同的群集主服务器不是共享的全局主机?例如创建新实例myCluster = new cluster()
?
在NodeJS中使用新的集群模块一段时间后,我遇到了两个单独的集群重叠的问题。不管您从何处require
,集群模块在当前运行的进程中都是全局的,两个不同的库(npm软件包)可以访问同一集群主服务器。
从任何库调用
cluster.workers
将列出每个库产生的每个工作程序。
每个人都在疯狂地讨论它的简单性和效率,但是遇到两个使用同一集群的库的问题后,我担心一个会通过使用某些全局集群来干扰另一个函数,例如cluster.disconnect()
,或访问全局工作程序对象cluster.workers
。我知道这是一个相当单一的用例模块,“创建一个可自我维持的一次性工作者集群,可以通过看门狗轻松地重新启动它。”
但这是多线程任务最简单的解决方案,child_process
使很多麻烦事倍受困扰。如果两个图书馆认为有必要使用cluster
,却没有努力跟踪哪些工人属于他们,而是称其为厚脸皮
Object.values(cluster.workers).forEach(worker => worker.kill())
作为他们的清理工作?
集群是否可以有两个不同的“实例”或“命名空间” ,以免干扰任何其他集群主服务器?还是集群模块只是您必须接受的全局变量?
我已经深入研究了文档,但是据我所知,无法通过调用myCluster = new cluster()
或将某些唯一的标识传递给派生的工人来创建新的集群实例。我感到惊讶的是,没有明显的解决方案可以解决此问题,尤其是考虑到它针对的是不应该存在此类问题的企业应用程序。
编程的趋势(并且已经有一段时间了)是远离全局实例,并创建仅了解它们需要知道的所谓的“哑组件”的自足实例。集群是NodeJS的一个相当新的功能,他们是否决定半实施一项重要功能?
对于您对此问题的想法或解决方法,我将不胜感激。现在,我正在创建一个可以从任务分配中大大受益的库,但是我不想弄脏依赖于程序包的全局群集。我应该使用低级child_process
吗?
非常感谢!
答案 0 :(得分:1)
切换到较低级别的child_process
模块后,出于一个简单的原因,我恢复了回到使用cluster
的状态。 Node.js的--inspect
调试器。
在调试另一个程序包很费劲之后,我将错误追溯到一个依赖关系,该依赖关系是我自己的实现child_process
方法的库。它是使用从父进程继承的child-process
分叉的execArgs
,这意味着child_process
试图与父进程绑定到 same 检查器端口,静默失败并崩溃。
虽然我的第一个解决方法是为child_process
生成一个随机的免费(由OS分配)调试端口,但这是一个有效的解决方法,但是却带来了自己的问题。最重要的是,该过程必须通过每次复制唯一端口来手动附加到调试器。
VS Code具有神奇的autoAttachChildProcesses
,它可以发现分叉的进程,但仅在使用cluster
时才发现,至少就我而言。似乎cluster
在派生过程中有一些涂糖,使其在调试过程中更易于发现和适应,或者VS Code仅侦听cluster.fork()
。我屈服于使我的工作人员对整个应用程序可见的缺点,而希望为用户提供更可靠的体验。
这是令人讨厌的行为,在GitHub上存在未解决的问题:https://github.com/nodejs/node/issues/9435
我的结论是,集群模块可提供更统一的分叉体验以及更智能的流程处理和发现,而程序包则必须尊重从不接触cluster.workers
或类似的全局功能,而应保持由cluster.fork()
返回的自己的工人数组。
答案 1 :(得分:0)
没有是的。
请参见,因为用节点术语进行集群意味着对当前进程进行分叉,所以实际上没有集群-只是forks列表= worker。
但是:您可以派生并要求您想要将派生作为工作程序的脚本(或if-else放入一个块中),然后将该新工作程序保存到自己的数组= cluster / fork_list中。
我有一个简单的支持模块,用于分隔工作程序脚本(并仅加载不同的脚本+处理通信):runworker