(译)使用PM2方便开启node集群模式

这篇文章 写的不错,通过这篇文章你可以了解node集群的原理及如果使用pm2快速方便的开启集群模式。

Introduction

As you would probably know, Node.js is a platform built on Chrome's JavaScript runtime, gracefully named V8.
The V8 engine, and hence Node.js, runs in a single-threaded way, therefore, doesn't take advantage of multi-core systems capabilities.

介绍

你也许知道,Node.js是一个运行在名叫V8的JavaScript引擎的平台系统。V8本身是单线程运行的,并没有充分利用多核系统能力。
(注:Node执行JS代码运行在V8上,是单线程,但并非真正的单线程架构)

Node.js cluster module

Luckily enough, Node.js offers the cluster module, which basically will spawn some workers which can all share any TCP connection.

How does it work ?

Cluster module will set up a master and then fork your server app as many times as you want it to (also called a worker).
It communicates with workers via IPC channels and comes with an embedded load-balancer which uses Round-robin algorithm to better distribute load among the workers.
When using Round-robin scheduling policy, the master accepts() all incoming connections and sends the TCP handle for that particular connection to the chosen worker (still via IPC).

How to use it ?

The most basic example is the following :

Node.js的集群模式

幸运的是,Node.js提供了集群模块,简单讲就是复制一些可以共享TCP连接的工作线程。

工作原理

集群模块会创建一个master主线程,然后复制任意多份程序并启动,这叫做工作线程。
工作线程通过 IPC 频道进行通信并且使用了 Round-robin algorithm 算法进行工作调度以此实现负载均衡。
Round-robin调度策略主要是master主线程负责接收所有的连接并派发给下面的各个工作线程。

如何使用

下面是一个很常见的例子:

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);
}

Of course, you can spawn as many workers as you wish. You're not limited by the CPU cores number since a worker is nothing more but a child process.
As you can see, to make it work, you have to wrap your code inside some cluster handling logic and then add some more code to specify the expected behaviour in case your worker dies unexpectedly.

你可以不受CPU核心限制的创建任意多个工作线程。
使用原生方法有些麻烦而且你还需要处理如果某个工作线程挂掉了等额外的逻辑。
(注:通过fork()复制的进程都是独立的进程,有着全新的V8实例)

The PM2 way
Built-in clustering

PM2 internally handles all of the above logic for you so you don't have to change anything in your code.
The previous code becomes :

PM2的方式
PM2内置了处理上述的逻辑,你不用再写这么多繁琐的代码了。
只需这样一行:
$ pm2 start app.js -i 4
-i <number of workers> 表示实例程序的个数。就是工作线程。
如果i为0表示,会根据当前CPU核心数创建

image.png

Keeping your apps running no matter what

If any of your workers happens to die, PM2 will restart them immediatly so you don't have to worry about that either.
Or, of course, you can, at any time, restart them manually as follows :

保持你的程序不中断运行

如果有任何工作线程意外挂掉了,PM2会立即重启他们,当前你可以在任何时候重启,只需:


image.png

Scaling your cluster in realtime

If you consider that you don't have enough workers or more than needed, you can scale your cluster anytime by hitting pm2 scale <app name> <n> where <n> can be a consistent number which the cluster will scale up or down to.
It can also be an addition such as pm2 scale app +3 in which case 3 more workers will be added to the cluster.

实时调整集群数量

你可以使用命令 pm2 scale <app name> <n> 调整你的线程数量,
如 pm2 scale app +3 会在当前基础上加3个工作线程。

image.png

Updating your apps in production with zero downtime

PM2 reload <app name> feature will restart your workers one by one, and for each worker, wait till the new one has spawned before killing the old one.
This way, your server keeps running even when you are deploying the new patch straight to production.

You can also use gracefulReload feature which does pretty much the same thing but instead of immediatly killing the worker it will send it a shutdown signal via IPC so it can close ongoing connections or perform some custom tasks before exiting gracefully.
Example :

在生产环境让你的程序永不中断

PM2 reload <app name> 命令会一个接一个的重启工作线程,在新的工作线程启动后才结束老的工作线程。
这种方式可以保持你的Node程序始终是运行状态。即使在生产环境下部署了新的代码补丁。

也可以使用gracefulReload命令达到同样的目的,它不会立即结束工作线程,而是通过IPC向它发送关闭信号,这样它就可以关闭正在进行的连接,还可以在退出之前执行一些自定义任务。这种方式更优雅。

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

Conclusion

Cluster module is a powerful tool. It gets even better and easy to use along with PM2.
Cluster.js was experimental on Node 0.10.x and is considered to be mature and production-ready since Node 0.11.x latest releases and of course Node 0.12.x.
We strongly suggest you to always use the latest version of Node.js and PM2 since both of these projects' contributors are working hard every day to make them better.

Enjoy Node.js' clustering with PM2 !

结论

Cluster集群模式非常强悍有用,此功能是在Node 0.10.x 是实验功能,在0.11.x 之后才作为正式发布。
强烈建议你使用最新版本的Node.js和PM2。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,254评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,875评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,682评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,896评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,015评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,152评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,208评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,962评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,388评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,700评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,867评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,551评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,186评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,901评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,689评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,757评论 2 351

推荐阅读更多精彩内容