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 server
http.createServer((req, res) => {
res.writeHead(200);
res.end('hello world\n');
}).listen(80);
}
上述简单的代码,就实现了根据CPU个数,创建多个worker。至于实际项目中,是正好一个核对应一个worker呢,还是一个核对应2、3个worker呢,就视情况而定了。如果项目中,等待其他服务器(例如数据库)响应特别长时间,设置2个以上worker应该会更好。
不过一般而言,一个CPU对一个worker就挺好的了。
那么,整个架构就类似这样:

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'));
}
});
按实际情况来看,效果是不错的。




3 平滑重启
每次发布新版本,服务器必然需要重启。
简单粗暴的,杀掉主进程,全部重启,必然会有一段时间的服务中断。

对于小企业还好,可以安排在凌晨重启,但对于大公司大产品来说,就不能这么粗暴了。
那么我们需要平滑重启,实现重启过程中,服务不中断。
策略并不复杂,但非常有效:
1、worker进程轮流重启,间隔时间;
2、worker进程并不是直接重启,而是先关闭新请求监听,等当前请求都返回了,再重启。
try {
// make sure we close down within 30 seconds
var 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) {
}
实施了平滑重启后,服务器的吞吐率会平滑很多。

node.js cluster多进程、负载均衡和平滑重启的更多相关文章
- 系列3|走进Node.js之多进程模型
文:正龙(沪江网校Web前端工程师) 本文原创,转载请注明作者及出处 之前的文章"走进Node.js之HTTP实现分析"中,大家已经了解 Node.js 是如何处理 HTTP 请求 ...
- node.js cluster模式启用方式
众所周知,Node.js运行在Chrome的JavaScript运行时平台上,我们把该平台优雅地称之为V8引擎.不论是V8引擎,还是之后的Node.js,都是以单线程的方式运行的,因此,在多核心处理器 ...
- node + nginx + mongo搭建负载均衡
基于node和nignx和mongo搭建负载均衡 nginx配置: upstream back { # ...
- Dubbo中集群Cluster,负载均衡,容错,路由解析
Dubbo中的Cluster可以将多个服务提供方伪装成一个提供方,具体也就是将Directory中的多个Invoker伪装成一个Invoker,在伪装的过程中包含了容错的处理,负载均衡的处理和路由的处 ...
- Node.js:多进程
ylbtech-Node.js:多进程 1.返回顶部 1. Node.js 多进程 我们都知道 Node.js 是以单线程的模式运行的,但它使用的是事件驱动来处理并发,这样有助于我们在多核 cpu 的 ...
- [Node.js] Cluster,把多核用起来
原文地址: http://www.moye.me/?p=496 引子 众所周知,虽然Node的底层有一个IO线程池,但其应用层默认是单线程运行的,对于多核CPU环境来说,是一种资源的浪费. 所幸Nod ...
- 为什么要使用 Node.js
这是一个移动端工程师涉足前端和后端开发的学习笔记,如有错误或理解不到位的地方,万望指正. Node.js 是什么 传统意义上的 JavaScript 运行在浏览器上,这是因为浏览器内核实际上分为两个部 ...
- 为什么要用 Node.js
每日一篇优秀博文 2017年10月10日 周二 为什么要用 Node.js 这是一个移动端工程师涉足前端和后端开发的学习笔记,如有错误或理解不到位的地方,万望指正. Node.js 是什么 传统意义上 ...
- Node.js的概念与应用
转:http://blog.jobbole.com/100058/?utm_source=blog.jobbole.com&utm_medium=relatedPosts Node.js 是什 ...
随机推荐
- C++中,指针数组和数组指针
这俩兄弟长得实在太像,以至于经常让人混淆.然而细心领会和甄别就会发现它们大有不同. 前者是指针数组,后者是指向数组的指针.更详细地说. 前: 指针数组;是一个元素全为指针的数组. 后: 数组指针;可以 ...
- php 解析 视频 信息 封面 标题 图片 支持 优酷, 土豆 酷6 56 新浪 qq播客 乐视 乐视
原文地址:http://www.lianyue.org/2013/2497/ <?php /** * 解析 视频信息 类 * * 支持 优酷, 土豆 酷6 56 新浪 qq播客 乐视 乐视 ** ...
- Android的Activity屏幕切换动画-左右滑动切换
. --> 在Android开发过程中,经常会碰到Activity之间的切换效果的问题,下面介绍一下如何实现左右滑动的切换效果,首先了解一下Activity切换的实现,从Android2.0开始 ...
- GATK使用说明(一)
1. 官方网址 https://software.broadinstitute.org/gatk/ 2. 下载Latest version: 3.7 3. FileZilla 上传至服务器,解压 ta ...
- [linux] 线程和wait命令,sleep命令
在linux脚本编程中使用多线程编程,其中wait命令可以实现shell的多线程同步控制. 1. 启动后台子任务 在执行命令后加&操作符,表示将命令放在子shell中异步执行.可以达到多线程效 ...
- sql sever 2008修改数据类型
如果是新表,直接在表中修改: 如果不是新表,则须sql语句修改 附sql语句 alter table 表名 alter column 列名 新的数据类型
- 触动——beyond歌词
1.一霎那,仿佛,若有所失的感觉 2.远路无法看的清 3.无悔这一生
- c# 验证码类
using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; us ...
- Java中FileOutputStream和FileInputStream使用例子
package a.ab; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.F ...
- Divide Two Integers leetcode
题目:Divide Two Integers Divide two integers without using multiplication, division and mod operator. ...