node集群cluster

node集群cluster

cludter

node实例是单线程作业的,在服务端编程中,通常会创建多个node实例来处理客户端的请求,以此来提升系统的吞吐率,对这样多个node 实例,称之为cludter

集群有以下两种常见的实现方案,但是node自带的cluster模块,采用了方案2

方案一

集群内的node实例,各自监听不同的端口,再由反向代理实现请求到多个端口的分发

  • 优点:实现简单,各实例相互独立
  • 缺点:增加端口占用,进程之间通信比较麻烦

方案二

集群内,创建一个主进程(master),以及若干个子进程(worker)。由master监听客户端连接请求,并根据特定的策略,转发给worker

  • 优点:通常只占用一个端口,通信相对简单,转发策略更灵活
  • 缺点:实现相对复杂,对主进程的稳定性要求较高

举例:

创建与CPU数目相同的服务端实例,来处理客户端请求。他们监听的都是同样的端口

// server.js
var cluster = require("cluster");
var cpuNums = require("os").cpus().length;
var http = require("http");
if(cluster.isMaster){
  for(var i = 0; i < cpuNums; i++){
    cluster.fork();
  }
}else{
  http.createServe(function(req, res){
    res.end(`response from worker ${process.pid}`);
  }).listen(3000);
  console.log(`worker ${process.pid} start`);
}

// 创建批处理脚本:./req.sh
#!/bin/bash
for((i=1;i<=4;i++)); do
    curl http://127.0.0.1:3000   //发出GET请求
    echo ""
done
 
//输出
    response from worker 23735
    response from worker 23731
    response from worker 23729
    response from worker 23730

cluster 模块实现原理

问题一:master、worker 如何通信?

master 进程通过 cluster.fork()来创建 worker 进程,cluster.fork()内部是通过 clild_process.fork()来创建子进程

  • master进程、worker进程是父进程与子进程的关系
  • master进程、worker进程可以通过 IPC 通道进行通信
问题二:如何实现端口共享
const net = require("net");
const server = net.createServer();

net模块中,对listen()方法进行了特殊处理,根据当前进程是master进程还是worker进程:

  • master进程:在该端口上正常监听请求(没做特殊处理)
  • worker进程:创建 serve 实例,然后通过IPC通道,向master进程发送消息,让master进程也创建serve实例,并在该端口上监听请求。当请求进来时,master进程将请求转发给worker进程的serve实例

注意:

主进程master并不会真正去监听端口,端口监听工作始终会交给主进程来完成,主进程在接到子进程worker发来的端口监听的时候,首先会判断是否有相同的服务器,如果有,就直接将子进程worker绑定到对应服务器上,这样就不会出现端口被占用的问题,如果没有对应的服务,就生成一个新的服务。主进程master接受请求时候,就会将请求任务分配给工作进程,如何分配,就需要看具体使用的哪种负载均衡了。

归纳:master进程监听特定端口,并将客户请求转发给worker进程

问题三:如何将请求分发到多个worker

每当worker进程创建server实例来监听请求,都会通过IPC通道,在master上进行注册。当客户端请求到达,master会负责将请求转发给对应的worker

至于转发给那个worker,这个是由转发策略决定的,可以通过环境变量NODE_CLUSTER_SCHED_POLICY设置,也可以在 cluster.setupMaster(options)时传入,默认的转发策略是轮询(SCHED_RR)当有用户请求到达,master会轮询一遍worker列表,找到第一个空闲的worker,然后将请求转发给该worker

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Node.js 中,可以使用 cluster 模块来实现集群cluster 模块允许我们创建一个主进程(称为主节点),然后创建多个子进程(称为工作节点)来处理请求。这些工作节点可以在同一台计算机上,也可以在不同的计算机上。 下面是一个简单的示例: ```javascript const cluster = require('cluster'); const http = require('http'); const numCPUs = require('os').cpus().length; if (cluster.isMaster) { console.log(`Master ${process.pid} is running`); // Fork workers. for (let i = 0; i < numCPUs; i++) { cluster.fork(); } cluster.on('exit', (worker, code, signal) => { console.log(`worker ${worker.process.pid} died`); }); } else { // Workers can share any TCP connection // In this case it is an HTTP server http.createServer((req, res) => { res.writeHead(200); res.end('hello world\n'); }).listen(8000); console.log(`Worker ${process.pid} started`); } ``` 在这个示例中,我们首先检查当前进程是否为主进程。如果是,我们创建多个子进程并在它们之间分配请求,否则,我们创建一个 HTTP 服务器来处理请求。 在这个示例中,我们使用了 `os` 模块来获取计算机的 CPU 数量,然后为每个 CPU 创建一个子进程。我们还监听了 `exit` 事件以处理工作节点的异常退出。 要运行这个示例,可以使用以下命令: ``` $ node app.js ``` 这将启动主进程和多个子进程来处理请求。由于每个子进程都是独立运行的,因此可以在同一台计算机上处理更多的请求,也可以在多台计算机上创建工作节点来处理更多的请求。 需要注意的是,在使用集群时,我们需要确保我们的应用程序是可扩展的,并且可以在多个工作节点上运行而不会出现问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值