Cluster 如何跟上 Node 的单线程概念?

Posted

技术标签:

【中文标题】Cluster 如何跟上 Node 的单线程概念?【英文标题】:How does Cluster keeps up with Node's single thread concept? 【发布时间】:2013-02-10 18:51:10 【问题描述】:

当你使用集群之类的东西分叉或启动多个工作人员时:

    是否正在创建多个线程或节点进程实例?这是否打破了 Node 的单线程概念?

    worker 之间的请求是如何处理的? Cluster 是否提供了一些智能机制来将所有请求负载均衡到多个工作人员?

【问题讨论】:

【参考方案1】:

Cluster 使用fork,是的,它会自动平衡:

工作进程是使用child_process.fork 方法生成的,因此它们可以通过 IPC 与父进程通信并来回传递服务器句柄。

[...]

当多个进程都accept()ing 在同一个底层资源上时,操作系统可以非常有效地在它们之间进行负载平衡。 Node.js 或您的程序中没有路由逻辑,工作人员之间也没有共享状态。因此,重要的是设计您的程序,使其不会过于依赖内存中的数据对象来进行会话和登录等操作。

如果您将新的 node.js 实例视为另一个线程,您可能会认为这打破了 node.js 单线程概念,但是请记住,对给定请求的所有回调都将在同一个节点上处理。 accepted 原始请求的 js 实例。没有竞争条件,没有共享数据,只有相当安全的进程间通信。

请参阅Cluster documentation 了解更多信息。

【讨论】:

共享资源呢?因此,2 个分叉服务于自己的请求,在同一资源上调用 fs.readdirAsync() 之类的东西,两个调用都会立即返回,但我认为在内部,存在资源竞争,不是吗? @User117:我不知道实际的实现,但读取目录通常意味着调用操作系统工具。此调用可能更喜欢其中一个进程,但是,操作系统的工作是相应地安排具有相同优先级的任务。但毕竟,node.js 的强大之处在于它的异步性——在等待回调的同时做其他事情。 谢谢。我也这么想,但不确定。【参考方案2】:

Cluster 是为了弥补node.js 的单线程架构而开发的。现代处理器具有多个内核,单线程进程将无法利用可用内核。它确实偏离了它的单线程架构,但它从来都不是坚持它的计划。主要概念是异步的、事件驱动的执行。

Cluster 使用 fork 创建进程。一个分叉的进程确实是它的 拥有自己的地址空间的自己的进程 - 没有什么 孩子可以(通常)影响其父母或兄弟姐妹的地址 空间(不像线程)。除了将所有方法放在一个 普通的 ChildProcess 实例,返回的对象有通信 通道内置。所有分叉的进程都可以使用这个进行通信 频道。

注意这里的细微差别:它不是multi-threaded,它只是创建新的独立进程。请参阅此处Threads vs Processes in Linux 进行比较。每个工作人员都像以前一样采用单线程架构。所以它不会破坏节点的单线程概念。

负载平衡取决于您的代码本身(因为每个代码都是独立的)和操作系统。操作系统在所有分叉进程和原始进程之间平均平衡负载。

但是,如果您希望以不同的方式进行操作,也是可以的。如果您使用主线程与工作线程不同,或者每个工作线程专门从事不同的任务(压缩/ffmpeg),您可以这样做。

【讨论】:

以上是关于Cluster 如何跟上 Node 的单线程概念?的主要内容,如果未能解决你的问题,请参考以下文章

node 进阶 | 通过node中如何捕获异常阐述express的特点

node.js与浏览器的单线程

node.js的单线程异步是什么意思呢?(转)

node.js使用cluster实现多进程

如何在 Ubuntu 中跟上最新版本的 Node.js?购电协议?编译?

Node.js 单线程模型