介绍

  众所周知,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. linux中redis的php扩展安装

    PHP中的扩展一般都是在安装环境的时候就已经装好了的.但是有的一些扩展在后期想要加上去的话也是可以的.php支持后期安装扩展. 想要安装扩展就需要先去下载安装扩展所需要的扩展源码包.autoconf. ...

  2. 快速上手seajs——简单易用Seajs

    快速上手seajs——简单易用Seajs   原文  http://www.cnblogs.com/xjchenhao/p/4021775.html 主题 SeaJS 简易手册 http://yslo ...

  3. PHP函数、数组

    PHP函数 PHP的真正威力源自于它的函数函数是通过调用函数来执行的,可以在页面的任何位置调用函数 PHP函数准则:函数名称以字母或下划线开头(不能以数字开头)函数的名称应该提示出它的功能 四要素:返 ...

  4. redmine整合GIT版本库

    redmine整合GIT版本库   服务器的环境: Ubuntu 11.10 64位 Redmine 1.4.5.stable.10943 git version 1.7.5.4 + gitolite ...

  5. nodejs复习05

    stream 可读流 fs.pause()方法会使处于流动模式的流停止触发data事件,切换到非流动模式并让后续数据流在内部缓冲区 var fs = require('fs') var rs = fs ...

  6. iOS之 利用通知(NSNotificationCenter)获取键盘的高度,以及显示和隐藏键盘时修改界面的注意事项

    我们在开发中会遇到这样的情况:调用键盘时需要界面有一个调整,避免键盘遮掩输入框. 但实现时你会发现,在不同的手机上键盘的高度是不同的.这里列举一下: //获取键盘的高度 /* iphone 6: 中文 ...

  7. 利用注解来保存uri

    一直对getRequestURI()与getRequestURL()理解不透彻,因此今天通过查找资料,现将些许收获分享一下: [非原创]代码搬运工..(*^__^*) 1.request.getSch ...

  8. Linux添加开机启动命令

    1.vi /etc/rc.d/rc.local 添加要启动的命令 如: service php-fpm start  //这样,开机就自动启动了php扩展 2. crontab -e   //是写定时 ...

  9. 弱省互测#0 t1

    题意 给一个\(N \times M\)的01网格,1不能走,从起点\((1, 1)\)走到\((N, M)\),每次只能向下或向右走一格,问两条不相交的路径的方案数.(n, m<=1000) ...

  10. C++:一般情况下,设计函数的形参只需要两种形式

    C++:一般情况下,设计函数的形参只需要两种形式.一,是引用形参,例如 void function (int &p_para):二,是常量引用形参,例如 void function(const ...