2012-03-22 60 views
28

有人可以详细解释核心cluster模块在Node.js中的工作原理吗?集群模块如何在Node.js中工作?

工作人员如何能够听到一个单一的端口?

据我所知,主进程执行监听,但是如何知道哪些端口要监听,因为在主进程之后启动了工作进程?他们是否通过child_process.fork沟通渠道以某种方式与主人沟通?如果是这样,到端口的传入连接是如何从主机传递给工作人员的?

另外我想知道什么逻辑是用来确定传入连接传递给哪个工作者?

+0

我对集群模块如何路由TCP请求有疑问。例如,我有Redis pubsub代码,npm集群中的每个工作人员正在接收消息;即使HTTP请求只被路由到一个工作者。有没有办法配置集群,以便只有一个工作者接收套接字请求,而不是所有的工人?我只是通过让主人持有pubsub侦听器,然后手动将其委派给每个工作人员来完成这项工作。但是,整个集群的重点是为您开箱即用...... – 2015-06-11 22:24:07

回答

12

我知道这是一个老问题,但现在这是在nodejs.org here:

解释工作进程正在使用的child_process催生.fork方法, ,以便它们可以通过IPC与父级进行通信,并通过服务器 来回处理。

当您在worker中调用server.listen(...)时,它会序列化 参数并将请求传递给主进程。如果主人 进程已经具有与工作人员的 要求匹配的监听服务器,则它将句柄传递给工作人员。如果它没有 已经有一个符合该要求的监听服务器,那么它将创建一个,并将句柄传递给worker。

这导致在三个边缘情况潜在地令人惊讶的行为:

server.listen({FD:7}) - 由于消息被传递到主,在父 文件描述符7进行监听的,并将句柄 传递给工作人员,而不是听取工作人员的想法 7号文件描述符引用的内容。

server.listen(手柄) - 听力上的把手明确将导致 工人使用附带的手柄,而不是跟主 过程。如果工作人员已经拥有句柄,那么推测你知道你在做什么。

服务器。listen(0) - 通常,这将导致服务器侦听 随机端口。但是,在一个集群中,每个工作人员每次收听(0)时都会收到相同的“随机”端口 。本质上,第一次随机的港口是 ,但此后可以预见。如果您希望 在唯一端口上侦听,请根据群集 工作者ID生成端口号。

当多个进程都接受()相同的基础资源时,操作系统在它们之间的负载平衡非常有效。 Node.js中或程序中没有路由逻辑,工作人员之间没有共享状态。因此, 设计您的程序非常重要,因为它不会过度依赖 内存中的数据对象来处理会话和登录等内容。

因为工人都是独立的进程,他们可以被杀死或根据程序的需要重新生成,而不会影响其他 工人。只要有一些工作人员仍然活着,服务器 将继续接受连接。但是,节点不会自动为您管理工作人员的数量。管理员工池以满足您应用程序的需求是您的责任。

8

NodeJS使用round-robin决定在子进程之间进行负载平衡。它将根据RR算法将传入连接提供给一个空进程。

孩子和父母实际上并没有共享任何东西,整个脚本从头到尾都被执行,这是正常的C fork之间的主要区别。传统C分叉的孩子会继续从它离开的指令开始执行,而不是像NodeJS那样的开始。所以如果你想分享任何东西,你需要连接到像MemCache或Redis这样的缓存。

所以下面的代码在控制台上产生6 6 6(没有恶意)。

var cluster = require("cluster"); 
var a = 5; 
a++; 
console.log(a); 
if (cluster.isMaster){ 
    worker = cluster.fork(); 
    worker = cluster.fork(); 
} 
+1

感谢您的循环信息,但我认为您误解了我关于连接传递的问题。我正在谈论进入共享端口的tcp连接,而不是如何在工作人员之间进行通信。 – Epeli 2012-03-22 22:27:25

+0

@Epeli此讨论可以帮助您解决以下问题:https://groups.google.com/forum/#!topic/nodejs/svIXu5wUXCI/discussion – Mustafa 2012-03-22 22:57:42

+2

我发现在Windows上它不遵守循环法。我可以派生10名工人,如果我的机器速度够快,它会将所有传入连接丢到第一个工人。有什么建议么? – 2012-06-13 19:59:52

4

这里是一个blog post,说明这一点

+3

请注意,只有链接的答案是不鼓励的,所以SO答案应该是搜索解决方案的终点(而另一个引用的中途停留时间往往会过时随着时间的推移)。请考虑在此添加独立的摘要,并将链接保留为参考。 – kleopatra 2013-08-04 09:32:27

0

作为@ OpenUserX03答案的更新,nodejs不再使用系统负载平衡,而是使用内置的负载平衡。从this post

修复Node v0.12使用循环法算法获得新的实现,以更好的方式在工作人员之间分配负载。这是节点自此之后使用的默认方法,包括节点v6.0.0