对Node.js集群模块的深入分析
集群模块概述
节点实例是单线程作业。在服务器端编程中,通常会创建多个节点实例来处理客户端请求,从而提高系统的吞吐量。对于这样的多节点实例,我们称之为集群。
有了node的集群模块,开发者可以在不修改原项目代码的情况下获得集群服务的好处。
集群有以下两种常见的实现方案,节点带来的集群模块采用第二种方案。
场景1:多个节点实例和多个端口
集群中的节点实例监听不同的端口,然后反向代理将请求分发到多个端口。
优点:实现简单,每个实例相对独立,有利于服务稳定性。缺点:增加端口占用会使进程之间的通信变得麻烦。方案二:主进程将请求转发给子进程
在集群中,创建了一个主进程和几个子进程。主服务器监控客户端连接请求,并根据特定策略将其转发给工作服务器。
优点:通常只占用一个端口,通信相对简单,转发策略更灵活。缺点:实现比较复杂,需要主流程的稳定性。入门示例
在集群模块中,主进程称为master,子进程称为worker。
示例如下:创建具有相同数量CPU的服务器实例来处理客户端请求。请注意,它们都在同一个端口监听。
//server . jsvar cluster=require(' cluster ');var cpuNums=required(' OS ')。CPU()。长度;var http=require(' http ');if(cluster . Ismaster){ for(var I=0;一.公共部门会计准则;I){ cluster . fork();} } else { http . CreateServer(function(req,res){ res.end(`来自worker ${process.pid}的响应`);}).听(3000);console . log(` worker $ { process . PID }已启动`);}创建批处理脚本:/req.sh。
#!/bin/bash # req . shfor((I=1;I=4;);do curl http://127 . 0 . 0 . 1:3000 echo ' '的输出如下。如您所见,响应来自不同的过程。
工作人员23735的响应工作人员23731的响应工作人员23729的响应工作人员23730的响应
集群模块的实现原理
了解集群模块,主要找出三个问题:
师傅,工人怎么沟通?如何与多个服务器实例共享端口?使用多个服务器实例,如何将来自客户端的请求分发到多个工作人员?下面将用示意图介绍。关于源代码级别的介绍,请参考作者的github。
问题1:1:主人和工人如何沟通
这个问题比较简单。主进程通过cluster.fork()创建一个工作进程。Cluster.fork()通过child_process.fork()在内部创建子进程。
也就是说:
主进程和工作进程是父进程和子进程之间的关系。主进程和woker进程可以通过IPC通道进行通信。(重要)问题2:如何实现端口共享
在前面的例子中,在多个woker中创建的服务器监听同一个端口3000。一般来说,如果多个进程监听同一个端口,系统会报错。
为什么我们的例子没问题?
秘密在于listen()方法是在net模块中专门处理的。根据当前进程是主进程还是工作进程:
主进程:正常监听此端口上的请求。(无特殊处理)工作进程:创建服务器实例。然后通过IPC通道向主进程发送消息,这样主进程也可以创建一个服务器实例,监听端口上的请求。当请求到来时,主进程将请求转发给工作进程的服务器实例。总而言之,主进程监听特定的端口,并将客户请求转发给工作进程。
如下图所示:
问题3:如何将请求分发给多个工作人员
每次工作进程创建一个服务器实例来监听请求时,它都会通过IPC通道在主机上注册。当客户端请求到达时,主机将负责将请求转发给相应的工作人员。
给哪个工人?这由转发策略决定。它可以由环境变量NODE _ CLUSTER _ SCHED _ POLICY设置,也可以在cluster.setupMaster(选项)处传入。
默认转发策略是轮询(SCHED_RR)。
当客户请求到达时,主人将轮询一次工人列表,找到第一个空闲的工人,然后将请求转发给工人。
掌握和工人的内部沟通技巧
在开发过程中,我们将通过process.on('message ',fn)实现进程间通信。
如前所述,在创建服务器实例的过程中,主进程和工作进程也通过IPC通道进行通信。这会干扰我们的发展吗?比如收到一堆你并不真正需要关心的信息?
答案肯定是否定的?那么是如何做到的呢?
当发送的消息包含cmd字段并且修改后的字段以NODE_为前缀时,该消息将被视为内部保留的消息,该消息不会被消息事件抛出,但可以通过侦听' internalMessage '来捕获。
以工作进程通知主进程创建服务器实例为例。工人伪代码如下:
//woker process const message={ cmd : ' node _ cluster ',act 3360 ' query server ' };process.send(消息);主伪码如下:
worker . process . on(' internal message ',fn);相关链接
正式文件:https://nodejs.org/api/cluster.html
节点研究注释:https://github.com/chyingp/nodejs-learning-guide
以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。
版权声明:对Node.js集群模块的深入分析是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。