Node.js clustering made easy with PM2

来源:互联网 发布:申万宏源手机炒股软件 编辑:程序博客网 时间:2024/05/29 04:53

这篇文章解释了PM2是如何实现集群的,其实就是利用了node自V.08推出的集群包cluster,但是直到V.10.X,该包始终是实验性的,并且确实,通过实验证实其集群性能确实存在问题,自V.11.X开始,该包才被认为是成熟的,并且可以用于生产。所以PM2一直强调,针对V.10.X是不被支持集群的-i模式。
Node.js clustering made easy with 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 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 usesRound-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 :

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.

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 :

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

Then you type :

$ pm2 start app.js -i 4

-i <number of workers> will tell PM2 that you want to launch your app in cluster_mode (as opposed to fork_mode).

If 'number of workers' argument is 0, PM2 will automatically spawn as many workers as you have CPU cores. 

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 : 

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 :

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 Node.js (0.12.x) and PM2 (0.12.10) versions since both of these projects' contributors are working hard every day to make them better.

Enjoy Node.js' clustering with PM2 !

0 0
原创粉丝点击