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 单线程概念,但是请记住,对给定请求的所有回调都将在同一个节点上处理。 accept
ed 原始请求的 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的特点