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多进程、负载均衡和平滑重启的更多相关文章

  1. 系列3|走进Node.js之多进程模型

    文:正龙(沪江网校Web前端工程师) 本文原创,转载请注明作者及出处 之前的文章"走进Node.js之HTTP实现分析"中,大家已经了解 Node.js 是如何处理 HTTP 请求 ...

  2. node.js cluster模式启用方式

    众所周知,Node.js运行在Chrome的JavaScript运行时平台上,我们把该平台优雅地称之为V8引擎.不论是V8引擎,还是之后的Node.js,都是以单线程的方式运行的,因此,在多核心处理器 ...

  3. node + nginx + mongo搭建负载均衡

    基于node和nignx和mongo搭建负载均衡 nginx配置: upstream back {                                                  # ...

  4. Dubbo中集群Cluster,负载均衡,容错,路由解析

    Dubbo中的Cluster可以将多个服务提供方伪装成一个提供方,具体也就是将Directory中的多个Invoker伪装成一个Invoker,在伪装的过程中包含了容错的处理,负载均衡的处理和路由的处 ...

  5. Node.js:多进程

    ylbtech-Node.js:多进程 1.返回顶部 1. Node.js 多进程 我们都知道 Node.js 是以单线程的模式运行的,但它使用的是事件驱动来处理并发,这样有助于我们在多核 cpu 的 ...

  6. [Node.js] Cluster,把多核用起来

    原文地址: http://www.moye.me/?p=496 引子 众所周知,虽然Node的底层有一个IO线程池,但其应用层默认是单线程运行的,对于多核CPU环境来说,是一种资源的浪费. 所幸Nod ...

  7. 为什么要使用 Node.js

    这是一个移动端工程师涉足前端和后端开发的学习笔记,如有错误或理解不到位的地方,万望指正. Node.js 是什么 传统意义上的 JavaScript 运行在浏览器上,这是因为浏览器内核实际上分为两个部 ...

  8. 为什么要用 Node.js

    每日一篇优秀博文 2017年10月10日 周二 为什么要用 Node.js 这是一个移动端工程师涉足前端和后端开发的学习笔记,如有错误或理解不到位的地方,万望指正. Node.js 是什么 传统意义上 ...

  9. Node.js的概念与应用

    转:http://blog.jobbole.com/100058/?utm_source=blog.jobbole.com&utm_medium=relatedPosts Node.js 是什 ...

随机推荐

  1. [转] MovieClip转Bitmap方法

    package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Loader; ...

  2. Markdown常用基本语法

    现在是我在学习Markdown时做的笔记.学完这些Markdown的基本使用已经不成问题. 1. 标题设置(让字体变大,和word的标题意思一样)在Markdown当中设置标题,有两种方式:第一种:通 ...

  3. expdp报错ora 39126

    11.2.0.2,expdp报错: ORA-39126: Worker unexpected fatal error in KUPW$WORKER.GET_TABLE_DATA_OBJECTS []O ...

  4. CentOS 7下源码安装MySQL 5.7

    网上说linux安装mysql服务分两种安装方法: ①源码安装,优点是安装包比较小,只有几十M左右,缺点是安装依赖的库多,安装编译时间长,安装步骤复杂容易出错: ②使用官方编译好的二进制文件安装,优点 ...

  5. Spring 4 官方文档学习(十一)Web MVC 框架之约定优于配置

    当返回一个ModelAndView时,可以使用其addObject(Object obj)方法,此时的约定是: An x.y.User instance added will have the nam ...

  6. VB6.0 调用存储过程

    最近有在做一个需求,需要在VB6.0中调用存储过程,整理了一下,供大家参考, 范例: Function callStoredProcedure(sEmployeeID As String, Optio ...

  7. java矩阵相乘的计算

    package a123; import java.util.Scanner; public class a132 { public static void main(String args[]) { ...

  8. 关于MySql数据库设计表与查询耗时分析

    本地建一张表persons,使用脚本插入了1000万条数据 下面比较几种查询方法的耗时(查询9000000到9000005这中间5条数据) 查询结果: 1: SELECT * FROM test.pe ...

  9. 找出单链表的倒数第K个(从1开始计数)结点的值

    typedef struct Link { int data; struct Link* next; }NODE,*pNODE; NODE *searchK(NODE *phead, int k) { ...

  10. CobarClient源码分析(1)

    CobarClient是阿里巴巴公司开发一个的开源的.基于iBatis和Spring的分布式数据库访问层.为了支持iBatis,Spring框架提供了一个SqlMapClientTemplate,通过 ...