Node.js使用PM2的集群将变得更加容易
介绍
众所周知,Node.js运行在Chrome的JavaScript运行时平台上,我们把该平台优雅地称之为V8引擎。不论是V8引擎,还是之后的Node.js,都是以单线程的方式运行的,因此,在多核心处理器的系统中并不能发挥其最大的性能。
Node.js的cluster模块
幸运的是,Node.js给我们提供了cluster模块,它可以生成多个工作线程来共享同一个TCP连接。
它是如何运作的呢?
首先,Cluster会创建一个master,然后根据你指定的数量复制出多个server app(也被称之为工作线程)。它通过IPC通道与工作线程之间进行通信,并使用内置的负载均衡来更好地处理线程之间的压力,该负载均衡使用了Round-robin算法(也被称之为循环算法)。
当使用Round-robin调度策略时,master accepts()所有传入的连接请求,然后将相应的TCP请求处理发送给选中的工作线程(该方式仍然通过IPC来进行通信)。
那如何来使用呢?
下面是一个最基本的例子:

var cluster = require('cluster');
var http = require('http');
var os = require('os');
var numCPUs = os.cpus().length;
if (cluster.isMaster) {
// Master:
// Let's fork as many workers as you have CPU cores
for (var i = 0; i < numCPUs; ++i) {
cluster.fork();
}
} else {
// Worker:
// Let's spawn a HTTP server
// (Workers can share any TCP connection.
// In this case its a HTTP server)
http.createServer(function(req, res) {
res.writeHead(200);
res.end("hello world");
}).listen(8080);
}

当然,你可以指定任意数量的工作线程,线程的数量不仅限于CPU核心的数量,因为它只是作为一个运行在CPU上的子线程。
正如你所看到的,要使其正常运行,你需要将你的代码封装到cluster的处理逻辑中,并添加一些额外的代码来指定当一个线程挂掉之后如何进行处理。
使用PM2的方式
内置的cluster
PM2内部包含了所有上述的处理逻辑,因此你不必对代码做任何修改。我们将上面的代码还原成最原始的形式:

var http = require('http');
http.createServer(function(req, res) {
res.writeHead(200);
res.end("hello world");
}).listen(8080);

然后在控制台执行:
$ pm2 start app.js -i 4
-i <number of workers>参数用来告诉PM2以cluster_mode的形式运行你的app(对应的叫fork_mode),后面的数字表示要启动的工作线程的数量。如果给定的数字为0,PM2则会根据你CPU核心的数量来生成对应的工作线程。

不论什么情况下,保持你的apps一直运行
如果任意一个工作线程挂掉了,不用担心,PM2会立即将其重启。当然,你也完全可以在任何时候手动重启这些线程:

实时扩展集群
任何时候,如果你需要增加工作线程的数量,可以通过pm2 scale <app name> <n>来对集群进行扩展。参数<n>指定工作线程的数量,被用来增加或减少集群数。你也可以通过pm2 scale app +3的方式来指定要增加多少工作线程。

在产品环境实现零停机更新
PM2的reload <app name>功能将依次重启所有的工作线程。每一个线程会等待在新的线程创建之后才会被终止掉,因此,当你在产品环境部署新的代码时,server会不间断地一直保持运行。
使用gracefulReload功能可以达到相同的目的,不同的是它不会立即终止工作线程,而是通过IPC发送一个shutdown信号来关闭所有当前的连接并处理一些自定义的任务,然后再优雅地退出。如下面的代码:

process.on('message', function(msg) {
if (msg === 'shutdown') {
close_all_connections();
delete_cache();
server.close();
process.exit(0);
}
});

将PM2配置成自动启动
想要PM2在服务器重启后自动运行之前的应用,可以先通过pm2 start启动你的应用,然后执行下面的命令:
pm2 save
这将在~/.pm2目录下生成一个dump.pm2文件,里面描述了当前PM2上运行着的所有应用。然后执行命令:
pm2 startup [platform]
注意有必要添加可选参数platform以明确告知pm2当前的系统环境。这样,下次当服务器重启时,PM2会自动运行之前保存的应用。
结论
Cluster模块的功能非常强大,使用PM2会使它变得更加容易。在Node 0.10.x时代cluster.js还只是个试验品,但从Node 0.11.x开始已经逐渐成熟并开始准备正式发布,当然也包括Node 0.12.x版本。强烈推荐使用最新版的Node.js和PM2,这些产品的贡献者们一直在努力并使它们变得更好。
尽情享受PM2带给Node.js集群操作的便利吧!
原文地址:https://keymetrics.io/2015/03/26/pm2-clustering-made-easy/
更多有关PM2的安装和使用可以查看这里的文档:http://pm2.keymetrics.io/docs/usage/quick-start/
Node.js使用PM2的集群将变得更加容易的更多相关文章
- Mongo副本集的配置以及php node.js连接使用副本集
最近弄了下mongodb的副本集, 首先说下没有认证情况的副本集,相对比较简单,因为环境有限,我在同一台服务器上做了模拟. --rest参数是打开web监控页面,比如我们这里监听37017端口,则打开 ...
- [Whole Web, Nods.js, PM2] Passing environment variables to node.js using pm2
learn how to pass environment variables to your node.js app using the pm2 config file. This is usefu ...
- node.js中pm2启动应用出错
在将公司的应用容器化时,遇到的问题. 之前,同事使用node.js 6版本运行,pm2启动js文件,一切正常. 但我一样将node.js 6版本安装,然后npm install pm2完成. 运行pm ...
- Node节点如何加入K8S集群
k8s集群中,有时候发现有些节点状态为 NotReady,如何修复为Ready状态呢? [root@k8s-master~]# kubectl get nodes NAME STATUS ROLES ...
- Node.js学习笔记(6)--异步变同步
说明(2017-5-3 14:59:03): 1. 异步变同步: var fs = require("fs"); var documents = []; fs.readdir(&q ...
- 使用PM2将Node.js的集群变得更加容易
介绍 众所周知,Node.js运行在Chrome的JavaScript运行时平台上,我们把该平台优雅地称之为V8引擎.不论是V8引擎,还是之后的Node.js,都是以单线程的方式运行的,因此,在多核心 ...
- 使用PM2管理Node.js集群
介绍 众所周知,Node.js运行在Chrome的JavaScript运行时平台上,我们把该平台优雅地称之为V8引擎.不论是V8引擎,还是之后的Node.js,都是以单线程的方式运行的,因此,在多核心 ...
- 使用 PM2 将 Node.js 的集群变得更加容易
介绍 众所周知,Node.js运行在Chrome的JavaScript运行时平台上,我们把该平台优雅地称之为V8引擎.不论是V8引擎,还是之后的Node.js,都是以单线程的方式运行的,因此,在多核心 ...
- master挂了的话pm2怎么处理 使用pm2方便开启node集群模式
本文为转载 Introduction As you would probably know, Node.js is a platform built on Chrome's JavaScript ru ...
随机推荐
- C++ 可配置的类工厂
项目中常用到工厂模式,工厂模式可以把创建对象的具体细节封装到Create函数中,减少重复代码,增强可读和可维护性.传统的工厂实现如下: class Widget { public: virtual i ...
- 【.net 深呼吸】细说CodeDom(3):命名空间
在上一篇文章中,老周介绍了表达式和语句,尽管老周没有把所有的内容都讲一遍,但相信大伙至少已经掌握基本用法.在本文中,咱们继续探讨 CodeDom 方面的奥秘,这一次咱们聊聊命名空间. 在开始之前,老周 ...
- 高大上的微服务可以很简单,使用node写微服务
安装 npm install m-service --save 使用 编写服务处理函数 // dir1/file1.js // 使用传入的console参数输出可以自动在日志里带上request id ...
- 06.LoT.UI 前后台通用框架分解系列之——浮夸的图片上传
LOT.UI分解系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#lotui LoT.UI开源地址如下:https://github.com/du ...
- .NET Core的日志[1]:采用统一的模式记录日志
记录各种级别的日志是所有应用不可或缺的功能.关于日志记录的实现,我们有太多第三方框架可供选择,比如Log4Net.NLog.Loggr和Serilog 等,当然我们还可以选择微软原生的诊断框架(相关A ...
- ASP.NET 5 RC1 升级 ASP.NET Core 1.0 RC2 记录
升级文档: Migrating from DNX to .NET Core Migrating from ASP.NET 5 RC1 to ASP.NET Core 1.0 RC2 Migrating ...
- 现代3D图形编程学习-基础简介(3)-什么是opengl (译)
本书系列 现代3D图形编程学习 OpenGL是什么 在我们编写openGL程序之前,我们首先需要知道什么是OpenGL. 将OpenGL作为一个API OpenGL 通常被认为是应用程序接口(API) ...
- Android Studio快捷键
一.android studio 默认快捷键 刚开始接触一款开发软件,想必很想了解它的快捷方式,这会对你的编程起到很好的帮助,提高工作效率,接下来给你介绍下Android Studio一些常用的快 ...
- Android菜单项内容大全
一.介绍: 菜单是许多应用中常见的用户界面组件. Android3.0版本以前,Android设备会提供一个专用"菜单"按钮呈现常用的一些用户操作, Android3.0版本以后, ...
- 《Note --- Unreal 4 --- Sample analyze --- StrategyGame(continue...)》
---------------------------------------------------------------------------------------------------- ...