介绍

  众所周知,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 

  -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/

使用PM2将Node.js的集群变得更加容易的更多相关文章

  1. 使用 PM2 将 Node.js 的集群变得更加容易

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

  2. Node.js的集群功能以及在Express的配置

    Node.js在v0.6.0版本下内置了集群功能,作为cluster模块,用于nodejs的多核处理,也比较容易通过脚本实现一个负载均衡的集群. 脚本参考了其他人的材料,建立一个server.js(因 ...

  3. 使用PM2管理Node.js集群

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

  4. 使用PM2守护Node.js应用

    PM2简介 PM2是node进程管理工具,可以利用它来简化很多node应用管理的繁琐任务,如性能监控.自动重启.负载均衡等,而且使用非常简单.   安装PM2 $ npm install pm2 -g ...

  5. K8S踩坑篇-master节点作为node节点加入集群

    前面我们二进制部署K8S集群时,三台master节点仅仅作为集群管理节点,所以master节点上中并未部署docker.kubelet.kube-proxy等服务.后来我在部署mertics-serv ...

  6. 使用pm2管理node.js应用

    中文文档:https://pm2.io/doc/zh/runtime/quick-start/ pm2是从nodejs衍生出来的服务器进程管理工具,可以做到开机就启动nodejs.当然了,有些运维同学 ...

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

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

  8. master挂了的话pm2怎么处理 使用pm2方便开启node集群模式

    本文为转载 Introduction As you would probably know, Node.js is a platform built on Chrome's JavaScript ru ...

  9. Kubernetes容器集群管理环境 - Node节点的移除与加入

    一.如何从Kubernetes集群中移除Node比如从集群中移除k8s-node03这个Node节点,做法如下: 1)先在master节点查看Node情况 [root@k8s-master01 ~]# ...

随机推荐

  1. 学习微信小程序之css5

    文本的装饰(下划线) 文本的位置,缩进

  2. GRU(Gated Recurrent Unit) 更新过程推导及简单代码实现

    GRU(Gated Recurrent Unit) 更新过程推导及简单代码实现 RNN GRU matlab codes RNN网络考虑到了具有时间数列的样本数据,但是RNN仍存在着一些问题,比如随着 ...

  3. 搭建ssm的领悟

    今天搭建了ssm,但是一直报错误 "Cannot load JDBC driver class 'com.mysql.jdbc.Driver" 我以为是版本的问题就换,以为是路径加 ...

  4. android 从 phonegap 到 js webview 交互

    像生活类.办公协同类. 动态添加,下载等. 1.phonegap 我这里用了旧的版本,可能新版本变化大了. 创建asset资源文件夹,然后新建index.html copy 相应的js 文件进来. 创 ...

  5. 队列的JS实现

    队列和栈相似,都是对插入和删除操作的部位做了限制特殊的线性表.在队列中,只能从一头删除节点,这一头叫做队首:而另一端只能做插入操作,这一头叫做队尾.很容易理解,队列是一个"先进先出" ...

  6. 【系统篇】从int 3探索Windows应用程序调试原理

    探索调试器下断点的原理 在Windows上做开发的程序猿们都知道,x86架构处理器有一条特殊的指令——int 3,也就是机器码0xCC,用于调试所用,当程序执行到int 3的时候会中断到调试器,如果程 ...

  7. linux工具

    sudo yum install yum-utils

  8. sublime 安装 插件

    从菜单 View - Show Console 或者 ctrl + ~ 快捷键,调出 console.将以下 Python 代码粘贴进去并 enter 执行,不出意外即完成安装.以下提供 ST3 和 ...

  9. WCF自动添加消息头

    客户端自定义消息查看器实现IClientMessageInspector接口在消息发送之前添加消息头 class ClientMessageInspector : System.ServiceMode ...

  10. css border属性做小三角标

    <!doctype html><html> <head> <title></title> <meta charset="ut ...