• 前言
  • 正文
  • 推荐资料
  • 附录:NodeJS学习网络资料整理
    • 1 从零开始 – 入门篇
    • 2 成为高手 – 进阶篇
    • 3 追根溯源 – 内核篇
    • 4 跨界应用 – 创造篇
    • 5 利剑在手 – 工具篇
    • 6 Web技术 – 应用篇

前言

首先,本篇主要讲述发生在项目实际部署NodeJS应用时遇到的多核CPU没有充分利用的实际问题。

其次,下列推荐有众多推荐文章,有说明如何在部署或者开发时充分利用多核CPU,提高应用性能及稳定系的解决思路和现有可行的技术解决方案。

最终,仅就我们这里讨论的部署NodeJS时充分利用CPU多核心问题,最有效的解决方案是通过PM2(Node应用管理器)进行线上部署

正文

前面我们有提到一个结论,部署NodeJS应用需要充分利用CPU多核心时,可以直接通过PM2(Node应用管理器)进行线上部署。

那么PM2是什么,通俗来说,PM2就是一个进程管理工具,它可以用管理你的node进程,并查看node进程的状态,当然也支持性能监控,进程守护,负载均衡等功能。

而它的主要特性如下:

  • 内建负载均衡(使用 Node cluster 集群模块)

  • 后台运行

  • 0 秒停机重载

  • 具有 Ubuntu 和 CentOS 的启动脚本

  • 停止不稳定的进程(避免无限循环)

  • 控制台检测

  • 提供 HTTP API

  • 远程控制和实时的接口 API(Nodejs 模块,允许和 PM2 进程管理器交互)

我们这里讨论暂不讨论PM2的其它特性,只说PM2 Clueter Mode。

The cluster mode allows networked Node.js applications (http(s)/tcp/udp server) to be scaled across all CPUs available, without any code modifications. This greatly increases the performance and reliability of your applications, depending on the number of CPUs available. Under the hood, this uses the Node.js cluster module such that the scaled application’s child processes can automatically share server ports. To learn more, see How It Works in the official Node.js documentation on the cluster module.

这段话是PM2 Cluster Mode的官网原文,其含义大致是说PM2的集群模式允许网络Node.js应用程序(http(s)/tcp/udp服务器)在所有可用的cpu上扩展,而不需要修改任何代码。这极大地提高了应用程序的性能和可靠性,这取决于可用cpu的数量。在底层,它使用Node.js集群模块,这样扩展后的应用程序的子进程可以自动共享服务器端口。最后告诉我们尽管用就是了,当然如果我们想了解更多信息怎么办,可以自己去官方Node.js文档查看Cluster集群模块的源码。

  1. PM2的安装部署很简洁,也很简单,执行npm install pm2 -g ,pm2就顺利安装到本地或者服务器上。
  2. PM2的使用也很简单,以下是PM2的常用命令和注释。

$ pm2 start app.js              # 启动app.js应用程序

$ pm2 start app.js -i 4         # cluster mode 模式启动4个app.js的应用实例     # 4个应用程序会自动进行负载均衡

$ pm2 start app.js --name="api" # 启动应用程序并命名为 "api"

$ pm2 start app.js --watch      # 当文件变化时自动重启应用

$ pm2 start script.sh           # 启动 bash 脚本

$ pm2 list                      # 列表 PM2 启动的所有的应用程序

$ pm2 monit                     # 显示每个应用程序的CPU和内存占用情况

$ pm2 show [app-name]           # 显示应用程序的所有信息

$ pm2 logs                      # 显示所有应用程序的日志

$ pm2 logs [app-name]           # 显示指定应用程序的日志

$ pm2 stop all                  # 停止所有的应用程序

$ pm2 stop 0                    # 停止 id为 0的指定应用程序

$ pm2 restart all               # 重启所有应用

$ pm2 reload all                # 重启 cluster mode下的所有应用

$ pm2 gracefulReload all        # Graceful reload all apps in cluster mode

$ pm2 delete all                # 关闭并删除所有应用

$ pm2 delete 0                  # 删除指定应用 id 0

$ pm2 scale api 10              # 把名字叫api的应用扩展到10个实例

$ pm2 reset [app-name]          # 重置重启数量

$ pm2 startup                   # 创建开机自启动命令

$ pm2 save                      # 保存当前应用列表

$ pm2 resurrect                 # 重新加载保存的应用列表

3. To enable the cluster mode, just pass the -i option :  pm2 start app.js -i max

max means that PM2 will auto detect the number of available CPUs and run as many processes as possible.(max表示PM2将自动检测可用CPU的数量并运行尽可能多的进程)

这也是充分利用多核CPU的关键,让PM2按可用的CPU数量帮我们创建多个进程,在实际测试中,我发现PM2检测的可用CPU数量实际是服务器的CPU逻辑处理器数量,不同于CPU核心数。尽管逻辑处理器数量可以通过超线程技术实现两倍CPU核心数,不过毕竟计算资源还是只有一份,遇到两个线程都要使用同样的计算单元时,还是得要排队,还要花时间在两个线程之前的协调工作上,所以整体工作效率的根本没有2倍,绝大多数时候能提升个20%-30%就不错了。(一个核同时执行两个线程

例:环境为一台4核cpu的ubuntu18的linux服务器,在singleCore.js所在目录下执行 pm2 start singleCore.js -i max后,可以查看到pm2当前为我们执行的nodejs应用创建了4个进程的cluster。

如上图二所示,我们执行 pm2 monit后,可以查看到pm2管理的每个nodejs应用的进程信息,此时可最大支持并发处理4个cpu密集型运算,当CPU密集型运算并发满时,CPU的4个线程都会满负荷进行运算,如果只有一个node进程时,只是只能接受到一个CPU密集型的运算请求,其他的都无法访问到node listen的端口,多进程好处高下立见。

以上,主要讨论是nodejs应用多核心cpu利用的一次实践,我们也提到了nodejs的cluster集群模块的设计是支持和实现nodejs应用实现利用多核CPU的关键所在,这里简单的讨论一下 nodejs的Cluster。nodejs老生常谈的特点是单线程,异步IO,事件循环。这里主要介绍Node的多进程技术,以及如何借助多进程方式来提升应用的可用性和性能。从严格意义上面来讲,Node并非真正的单线程架构,Node自身还有一定的I/O线程存在,这些I/O线程由底层libuv处理,这部分线程对于JavaScript开发者是透明的,只在C++扩展开发时才会关注到。JavaScript代码永远运行在V8上,是单线程的。现在围绕JavaScript部分展开,所以屏蔽底层细节的讨论。

推荐一篇生动介绍nodejs cluster进程分配演化过程的blog,贴一张结果图

round-robin 轮转算法的nodejs实现模型

代码demo

var cluster = require('cluster');

var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {

  console.log('[master] ' "start master...");

  for (var i = 0; i < numCPUs; i++) {

     cluster.fork();

  }

  cluster.on('listening'function (worker, address) {

    console.log('[master] ' 'listening: worker' + worker.id + ',pid:' + worker.process.pid + ', Address:' + address.address + ":" + address.port);

  });

else if (cluster.isWorker) {

  require('app.js');

}

//app.js就是开启具体的业务逻辑了

//app.js具体内容

const net = require('net');

//自动创建socket

const server = net.createServer(function(socket) { //'connection' listener

  socket.on('end'function() {

    console.log('server disconnected');

  });

  socket.on('data'function() {

    socket.end('hello\r\n');

  });

});

//开启端口的监听

server.listen(8124, function() { //'listening' listener

  console.log('working')

});

还有几篇博客推荐:

  • 【译】 Node.js v0.12的新特性 -- Cluster模式采用Round-Robin负载均衡
  • Nodejs cluster模块深入探究

讨论完nodejs cluster 模块,我们可以通过自己cluster.fork() 不同的worker来实现咱们自己的业务,接下来我们主要是讨论一下PM2究竟是如何利用nodejs 的 cluster module实现负载均衡的,以及我们究竟需不需要自己去开发cluster模块,还是说就把多进程的管理交给pm2来完成,我们还是只负责开发业务逻辑的实现,让pm2帮我们管理node应用的运行维护和负载均衡。

推荐资料

0、深入浅出Nodejs(书籍)

1、通过Node.js的Cluster模块源码,深入PM2原理

2、nodejs高大上的部署方式(PM2)

3、Nodejs官方文档之worker_threads模块

4、Pm2官方文档之Cluster Mode

5、NodeJS 充分利用多核CPU服务器处理高并发请求 (原文:一个前端工程师眼里的 NodeJS)

6、NodeJS充分利用多核CPU以及它的稳定性

7、Node内部工作原理解析

附录:NodeJS学习网络资料整理

1 从零开始 – 入门篇

准备Nodejs开发环境Ubuntu

Node.js开发框架Express4.x

Nodejs开发框架Express3.0开发手记–从零开始

Mongoose使用案例–让JSON数据直接入库MongoDB

Nodejs对MongoDB模糊查询

用Nodejs连接MySQL

Nodejs配合bootstrap-select下拉列表

nodejs分页设计配合bootstrap-paginator

nodejs豆瓣爬虫

玩转Nodejs日志管理log4js

Nginx反向代理Nodejs – log4js日志IP显示错误

upstart封装nodejs应用为系统服务

2 成为高手 – 进阶篇

Nodejs基础中间件Connect

grunt让Nodejs规范起来

bower解决js的依赖管理

Yeoman自动构建js项目

快速创建基于npm的nodejs库

CNPM搭建私有的NPM服务

NPM下载出错 No compatible version found

Nodejs实现websocket的4种方式

Socket.io在线聊天室

websocket服务器监控

Nginx反向代理Websocket

restify构建REST服务

jasmine行为驱动,测试先行

Karma和Jasmine自动化单元测试

Nodejs服务器管理模块forever

Express结合Passport实现登陆认证

Passport现实社交网络OAuth登陆

Nodejs发邮件组件Nodemailer

快速排序的Nodejs实现

桶排序的Nodejs实现

3 追根溯源 – 内核篇

解读Nodejs多核处理模块cluster

Nodejs创建HTTPS服务器

Nodejs异步异常处理domain

Nodejs加密算法库Crypto

Node.js缓冲模块Buffer

Node.js进程通信模块child_process

4 跨界应用 – 创造篇

Nodejs与R跨平台通信

tty.js打通浏览器与Linux的通道

用Highcharts轻松构建交互性图表

5 利剑在手 – 工具篇

RequireJS异步模块加载

Nodejs临时文件回收器reap

Nodejs异步流程控制Async

Async多任务时间管理

让Nodejs来管理定时任务later

wind.js助力异步编程

UnderscoreJS精巧而强大工具包

Commander写自己的Nodejs命令

Stylus让CSS也能编程

Browserify 跑在浏览器上的Node程序

Retry优雅的失败重试策略

用UglifyJS2合并压缩混淆JS代码

Marked高效的Markdown解析器

6 Web技术 – 应用篇

Hexo在github上构建免费的Web应用

Jekyll在github上构建免费的Web应用

用WebStorm编辑Markdown

30秒制作幻灯片 Cleaver

NodeJS应用部署之PM2(充分利用多核cpu)相关推荐

  1. NodeJS充分利用多核CPU以及它的稳定性

    NodeJS是基于chrome浏览器的V8引擎构建的,也就说明它的模型与浏览器是类似的.我们的javascript会运行在单个进程的单个线程上.这样有一个好处: 状态单一 没有锁 不需要线程间同步 减 ...

  2. nodejs 获取cpu核心数量_用 NodeJS 充分利用多核 CPU 的资源[每日前端夜话0xCB]

    每日前端夜话0xCA 每日前端夜话,陪你聊前端. 每天晚上18:00准时推送. 正文共:1558 字 预计阅读时间:7 分钟 作者:Nick Major 翻译:疯狂的技术宅 来源:coderrocke ...

  3. python多线程不能利用多核cpu,但有时候多线程确实比单线程快。

    python 为什么不能利用多核 CPU  GIL 其实是因为在 python中有一个 GIL( Global Interpreter Lock),中文为:全局解释器锁.  1.最开始时候设计GIL是 ...

  4. 内存墙,多核CPU的终结者?

    原文地址:http://www.ed-china.com/ART_8800045174_400004_500008_OT_8f4eb612.HTM 多核处理器是当今计算领域的主导,而多核芯片则遍布从苹 ...

  5. 程序 多核优化 linux,linux 多核CPU性能调优

    常常感觉系统资源不够用,一台机子上跑了不下3个比较重要的服务,但是每天我们还要在上面进行个备份压缩等处理,网络长时间传输,这在就很影响本就不够用的系统资源: 这个时候我们就可以把一些不太重要的比如co ...

  6. php-fpm 多核,linux 多核CPU性能调优

    常常感觉系统资源不够用,一台机子上跑了不下3个比较重要的服务,但是每天我们还要在上面进行个备份压缩等处理,网络长时间传输,这在就很影响本就不够用的系统资源: 这个时候我们就可以把一些不太重要的比如co ...

  7. Node.js 能否充分利用多核处理器?

    (默认的)Node.js 应用程序总是单线程的模型,即使在多核处理器上运行,应用程序也能只使用一个处理器. 但是 Node.js 的核心模块之一 Cluster 支持 Node.js 应用程序开启多核 ...

  8. go/node/python 多进程与多核cpu

    node node单线程,没有并发,但是可以利用cluster进行多cpu的利用.cluster是基于child_process的封装,帮你做了创建子进程,负载均衡,IPC的封装. const clu ...

  9. 如何利用多核CPU提高虚拟现实性能?

    虚拟现实引领新时代令人惊喜的新体验,但也带来了各种新的挑战.其中之一就是虚拟现实应用"耗能"问题. 虚拟现实挑战了图形和仿真技术,以至于创造优秀虚拟现实体验的硬件需求成为日前热点. ...

最新文章

  1. Java面向对象 第3节 类的封装和继承
  2. Java并发编程的基础-线程的终止
  3. Lazarus安装使用
  4. Eclipse扩展的轻量级集成测试
  5. java当前目录指什么_是什么决定了Tomcat Java进程的当前工作目录?
  6. 整数输入有理循环小数 1/7 = 0.142857142... 是个无限循环小数。 任何有理数都可以表示为无限循环小数的形式。 本题目要求即是:给出一个数字的循环小数表示法。...
  7. 应用安全-路由器安全-修复方案整理
  8. [C++11] 右值引用和移动语义
  9. python 正则表达式 re.sub_Python 正则表达式 re.match/re.search/re.sub的使用解析
  10. Unity3D基础12:碰撞体
  11. NXP iMX8 SCFW和Boot Container Image编译
  12. QCC3040 BLE bonding相关配置
  13. 从这里开始你的游戏黑客入门的之旅吧
  14. Ubuntu拼音打不了中文
  15. 理解Tensorflow的shape
  16. 在进行IBEACON定位时所应考虑到的误差与建议
  17. Java金额转换工具类
  18. Oracle数据库网络详解
  19. 关于String s=1.0 转为INT
  20. 赵小楼《天道》《遥远的救世主》深度解析(58)丁元英听到芮小丹说自已击毙了一个罪犯后心里的那一颤

热门文章

  1. laravel 中使用apidoc
  2. *7.1 (指定等级)编写一个程序,读入学生成绩,获取最高分 best, 然后根据下面的规则赋等级值
  3. php 二维数组更改键名
  4. 回归问题中的MAE,MSE,MAPE与R方
  5. 手机号码(验证,所在地查询)
  6. 云桌面服务器作用,云桌面服务器所需要具备的特点
  7. 黑客通过音乐监视你,这诡异的黑客技术太厉害了
  8. 尺寸单位rpx和px的区别
  9. 2678v3支持内存频率_E52680V2与E52678V3的区别
  10. 管理类联考——英语——知识篇——作文题材说明