node.js cluster多进程、负载均衡和平滑重启

2024-08-28 09:48

本文主要是介绍node.js cluster多进程、负载均衡和平滑重启,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1 cluster多进程

cluster经过好几代的发展,现在已经比较好使了。利用cluster,可以自动完成子进程worker分配request的事情,就不再需要自己写代码在master进程中robin式给每个worker分配任务了。

复制代码
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;if (cluster.isMaster) {// Fork workers.for (var 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 serverhttp.createServer((req, res) => {res.writeHead(200);res.end('hello world\n');}).listen(80);
}
复制代码

 

上述简单的代码,就实现了根据CPU个数,创建多个worker。至于实际项目中,是正好一个核对应一个worker呢,还是一个核对应2、3个worker呢,就视情况而定了。如果项目中,等待其他服务器(例如数据库)响应特别长时间,设置2个以上worker应该会更好。

不过一般而言,一个CPU对一个worker就挺好的了。

 

那么,整个架构就类似这样:

image

 

Master进程,需要做的就是监控worker的生命周期,如果发现worker挂掉了,就重启worker,并做好相应的log。

整个架构没有太大的难点,重点就是做好一些细节处理,例如重启、日志、5秒心跳包等。

 

多进程的架构,相对原始的单进程+pm2重启好处肯定多很多,整个node服务会更稳定,不会突然彻底挂了。

另外,对比pm2多进程,也有优势,主要是master的逻辑掌握在开发自己手中,可以做好自定义的log和邮件、短信告警。

 

为了整个nodejs服务管理方便,在master进程中,我们一般开启管理端口的监听,例如12701,通过命令行curl 127.0.0.1:12701:xxx发起一个简单的http get请求,轻松管理。

例如xxx传入reload,可以作为服务器重启的指令。

 

2 负载均衡

说到多进程,目的肯定是尽可能利用多核CPU,提高单机的负载能力。

但往往在实际项目中,受到业务逻辑的处理时间长短和系统CPU调度影响,导致实际上所有进程的负载并不是理想的彻底均衡。

官方也说了:

In practice however, distribution tends to be very unbalanced due to operating system scheduler vagaries. Loads have been observed where over 70% of all connections ended up in just two processes, out of a total of eight.

翻译一下:70%的请求最终都落到2个worker身上,而这2个worker占用更多的CPU资源。

那么在实际项目部署,我们可以尝试更进一步的措施:绑定CPU。4核CPU,我们fork出4个worker,每个worker分别绑定到#1-#4 CPU。

node并没有给我们提供现成的接口,不过我们可以使用linux的命令:taskset

在node中,我们可以使用child_process执行shell。

复制代码
cp.exec('taskset -cp ' + (cpu) + ' ' + process.pid,{ timeout: 5000 
},function(err,data,errData){ if(err){ logger.error(err.stack); } if(data.length){ logger.info('\n' + data.toString('UTF-8')); } if(errData.length){ logger.error('\n' + errData.toString('UTF-8')); } 
});
复制代码

 

按实际情况来看,效果是不错的。

imageimageimageimage

 

 

3 平滑重启

每次发布新版本,服务器必然需要重启。

简单粗暴的,杀掉主进程,全部重启,必然会有一段时间的服务中断。

image

对于小企业还好,可以安排在凌晨重启,但对于大公司大产品来说,就不能这么粗暴了。

 

那么我们需要平滑重启,实现重启过程中,服务不中断。

策略并不复杂,但非常有效:

1、worker进程轮流重启,间隔时间;

2、worker进程并不是直接重启,而是先关闭新请求监听,等当前请求都返回了,再重启。

复制代码
  try {// make sure we close down within 30 secondsvar killtimer = setTimeout(() => {process.exit(1);}, 30000);// stop taking new requests.
        server.close();// Let the master know we're dead.  This will trigger a// 'disconnect' in the cluster master, and then it will fork// a new worker.
        cluster.worker.disconnect();} catch (er2) {}
复制代码

 

实施了平滑重启后,服务器的吞吐率会平滑很多。

image

这篇关于node.js cluster多进程、负载均衡和平滑重启的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1114421

相关文章

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

SpringCloud之LoadBalancer负载均衡服务调用过程

《SpringCloud之LoadBalancer负载均衡服务调用过程》:本文主要介绍SpringCloud之LoadBalancer负载均衡服务调用过程,具有很好的参考价值,希望对大家有所帮助,... 目录前言一、LoadBalancer是什么?二、使用步骤1、启动consul2、客户端加入依赖3、以服务

SpringCloud负载均衡spring-cloud-starter-loadbalancer解读

《SpringCloud负载均衡spring-cloud-starter-loadbalancer解读》:本文主要介绍SpringCloud负载均衡spring-cloud-starter-loa... 目录简述主要特点使用负载均衡算法1. 轮询负载均衡策略(Round Robin)2. 随机负载均衡策略(

Linux中的进程间通信之匿名管道解读

《Linux中的进程间通信之匿名管道解读》:本文主要介绍Linux中的进程间通信之匿名管道解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、基本概念二、管道1、温故知新2、实现方式3、匿名管道(一)管道中的四种情况(二)管道的特性总结一、基本概念我们知道多

nvm如何切换与管理node版本

《nvm如何切换与管理node版本》:本文主要介绍nvm如何切换与管理node版本问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录nvm切换与管理node版本nvm安装nvm常用命令总结nvm切换与管理node版本nvm适用于多项目同时开发,然后项目适配no

Linux进程终止的N种方式详解

《Linux进程终止的N种方式详解》进程终止是操作系统中,进程的一个重要阶段,他标志着进程生命周期的结束,下面小编为大家整理了一些常见的Linux进程终止方式,大家可以根据需求选择... 目录前言一、进程终止的概念二、进程终止的场景三、进程终止的实现3.1 程序退出码3.2 运行完毕结果正常3.3 运行完毕

Windows命令之tasklist命令用法详解(Windows查看进程)

《Windows命令之tasklist命令用法详解(Windows查看进程)》tasklist命令显示本地计算机或远程计算机上当前正在运行的进程列表,命令结合筛选器一起使用,可以按照我们的需求进行过滤... 目录命令帮助1、基本使用2、执行原理2.1、tasklist命令无法使用3、筛选器3.1、根据PID

linux本机进程间通信之UDS详解

《linux本机进程间通信之UDS详解》文章介绍了Unix域套接字(UDS)的使用方法,这是一种在同一台主机上不同进程间通信的方式,UDS支持三种套接字类型:SOCK_STREAM、SOCK_DGRA... 目录基础概念本机进程间通信socket实现AF_INET数据收发示意图AF_Unix数据收发流程图A

Node.js net模块的使用示例

《Node.jsnet模块的使用示例》本文主要介绍了Node.jsnet模块的使用示例,net模块支持TCP通信,处理TCP连接和数据传输,具有一定的参考价值,感兴趣的可以了解一下... 目录简介引入 net 模块核心概念TCP (传输控制协议)Socket服务器TCP 服务器创建基本服务器服务器配置选项服

mac安装nvm(node.js)多版本管理实践步骤

《mac安装nvm(node.js)多版本管理实践步骤》:本文主要介绍mac安装nvm(node.js)多版本管理的相关资料,NVM是一个用于管理多个Node.js版本的命令行工具,它允许开发者在... 目录NVM功能简介MAC安装实践一、下载nvm二、安装nvm三、安装node.js总结NVM功能简介N