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常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

Hadoop集群数据均衡之磁盘间数据均衡

生产环境,由于硬盘空间不足,往往需要增加一块硬盘。刚加载的硬盘没有数据时,可以执行磁盘数据均衡命令。(Hadoop3.x新特性) plan后面带的节点的名字必须是已经存在的,并且是需要均衡的节点。 如果节点不存在,会报如下错误: 如果节点只有一个硬盘的话,不会创建均衡计划: (1)生成均衡计划 hdfs diskbalancer -plan hadoop102 (2)执行均衡计划 hd

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

Node.js学习记录(二)

目录 一、express 1、初识express 2、安装express 3、创建并启动web服务器 4、监听 GET&POST 请求、响应内容给客户端 5、获取URL中携带的查询参数 6、获取URL中动态参数 7、静态资源托管 二、工具nodemon 三、express路由 1、express中路由 2、路由的匹配 3、路由模块化 4、路由模块添加前缀 四、中间件

[Linux]:进程(下)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:Linux学习 贝蒂的主页:Betty’s blog 1. 进程终止 1.1 进程退出的场景 进程退出只有以下三种情况: 代码运行完毕,结果正确。代码运行完毕,结果不正确。代码异常终止(进程崩溃)。 1.2 进程退出码 在编程中,我们通常认为main函数是代码的入口,但实际上它只是用户级

EasyPlayer.js网页H5 Web js播放器能力合集

最近遇到一个需求,要求做一款播放器,发现能力上跟EasyPlayer.js基本一致,满足要求: 需求 功性能 分类 需求描述 功能 预览 分屏模式 单分屏(单屏/全屏) 多分屏(2*2) 多分屏(3*3) 多分屏(4*4) 播放控制 播放(单个或全部) 暂停(暂停时展示最后一帧画面) 停止(单个或全部) 声音控制(开关/音量调节) 主辅码流切换 辅助功能 屏

Node Linux相关安装

下载经编译好的文件cd /optwget https://nodejs.org/dist/v10.15.3/node-v10.15.3-linux-x64.tar.gztar -xvf node-v10.15.3-linux-x64.tar.gzln -s /opt/node-v10.15.3-linux-x64/bin/npm /usr/local/bin/ln -s /opt/nod

使用JS/Jquery获得父窗口的几个方法(笔记)

<pre name="code" class="javascript">取父窗口的元素方法:$(selector, window.parent.document);那么你取父窗口的父窗口的元素就可以用:$(selector, window.parent.parent.document);如题: $(selector, window.top.document);//获得顶级窗口里面的元素 $(

js异步提交form表单的解决方案

1.定义异步提交表单的方法 (通用方法) /*** 异步提交form表单* @param options {form:form表单元素,success:执行成功后处理函数}* <span style="color:#ff0000;"><strong>@注意 后台接收参数要解码否则中文会导致乱码 如:URLDecoder.decode(param,"UTF-8")</strong></span>

java 进程 返回值

实现 Callable 接口 与 Runnable 相比,Callable 可以有返回值,返回值通过 FutureTask 进行封装。 public class MyCallable implements Callable<Integer> {public Integer call() {return 123;}} public static void main(String[] args