Node.js——Cluster多进程模式与PM2的实现
<p>Node.js的Cluster多进程模式。</p><p>PM2的实现原理,它是基于Cluster模式的封装。</p>
<p> </p>
<p>Node.js,都是以单线程的方式运行的,因此,在多核心处理器的系统中并不能发挥其最大的性能。</p>
<h2>Node.js的cluster模块</h2>
<p> 幸运的是,Node.js给我们提供了cluster模块,它可以生成多个工作线程来共享同一个TCP连接。</p>
<p> 它是如何运作的呢?</p>
<p> 首先,Cluster会创建一个master,然后根据你指定的数量复制出多个server app(也被称之为工作线程)。它通过IPC通道与工作线程之间进行通信,并使用内置的负载均衡来更好地处理线程之间的压力,该负载均衡使用了Round-robin算法(也被称之为循环算法)。</p>
<p> 当使用Round-robin调度策略时,master accepts()所有传入的连接请求,然后将相应的TCP请求处理发送给选中的工作线程(该方式仍然通过IPC来进行通信)。</p>
<p> 那如何来使用呢?</p>
<p> 下面是一个最基本的例子:</p>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>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);
}</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<p> 当然,你可以指定任意数量的工作线程,线程的数量不仅限于CPU核心的数量,因为它只是作为一个运行在CPU上的子线程。</p>
<p> 正如你所看到的,要使其正常运行,你需要将你的代码封装到cluster的处理逻辑中,并添加一些额外的代码来指定当一个线程挂掉之后如何进行处理。</p>
<h2>使用PM2的方式</h2>
<h3>内置的cluster</h3>
<p> PM2内部包含了所有上述的处理逻辑,因此你不必对代码做任何修改。我们将上面的代码还原成最原始的形式:</p>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>var http = require('http');
http.createServer(function(req, res) {
res.writeHead(200);
res.end("hello world");
}).listen(8080);</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<p> 然后在控制台执行:</p>
<div class="cnblogs_code">
<pre>$ pm2 start app.js -i 4</pre>
</div>
<p> -i <number of workers>参数用来告诉PM2以cluster_mode的形式运行你的app(对应的叫fork_mode),后面的数字表示要启动的工作线程的数量。如果给定的数字为0,PM2则会根据你CPU核心的数量来生成对应的工作线程。</p>
<p><img src="https://images2015.cnblogs.com/blog/51946/201602/51946-20160217184505534-1546009164.png"></p>
<h3>不论什么情况下,保持你的apps一直运行</h3>
<p> 如果任意一个工作线程挂掉了,不用担心,PM2会立即将其重启。当然,你也完全可以在任何时候手动重启这些线程:</p>
<p><img src="https://images2015.cnblogs.com/blog/51946/201602/51946-20160217184901550-136196118.png"></p>
<h3>实时扩展集群</h3>
<p> 任何时候,如果你需要增加工作线程的数量,可以通过pm2 scale <app name> <n>来对集群进行扩展。参数<n>指定工作线程的数量,被用来增加或减少集群数。你也可以通过pm2 scale app +3的方式来指定要增加多少工作线程。</p>
<p><img src="https://images2015.cnblogs.com/blog/51946/201602/51946-20160217185718456-1796833337.png"></p>
<h3>在产品环境实现零停机更新</h3>
<p> PM2的reload <app name>功能将依次重启所有的工作线程。每一个线程会等待在新的线程创建之后才会被终止掉,因此,当你在产品环境部署新的代码时,server会不间断地一直保持运行。</p>
<p> 使用gracefulReload功能可以达到相同的目的,不同的是它不会立即终止工作线程,而是通过IPC发送一个<em>shutdown</em>信号来关闭所有当前的连接并处理一些自定义的任务,然后再优雅地退出。如下面的代码:</p>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>process.on('message', function(msg) {
if (msg === 'shutdown') {
close_all_connections();
delete_cache();
server.close();
process.exit(0);
}
});</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<h3>将PM2配置成自动启动</h3>
<p> 想要PM2在服务器重启后自动运行之前的应用,可以先通过pm2 start启动你的应用,然后执行下面的命令:</p>
<div class="cnblogs_code">
<pre>pm2 save</pre>
</div>
<p> 这将在~/.pm2目录下生成一个dump.pm2文件,里面描述了当前PM2上运行着的所有应用。然后执行命令:</p>
<div class="cnblogs_code">
<pre>pm2 startup </pre>
</div>
<p> 注意有必要添加可选参数platform以明确告知pm2当前的系统环境。这样,下次当服务器重启时,PM2会自动运行之前保存的应用。</p>
<h2>结论</h2>
<p> Cluster模块的功能非常强大,使用PM2会使它变得更加容易。在Node 0.10.x时代cluster.js还只是个试验品,但从Node 0.11.x开始已经逐渐成熟并开始准备正式发布,当然也包括Node 0.12.x版本。强烈推荐使用最新版的Node.js和PM2,这些产品的贡献者们一直在努力并使它们变得更好。</p>
<p> 尽情享受PM2带给Node.js集群操作的便利吧!</p>
<p>原文地址:https://keymetrics.io/2015/03/26/pm2-clustering-made-easy/</p>
<p>更多有关PM2的安装和使用可以查看这里的文档:http://pm2.keymetrics.io/docs/usage/quick-start/</p>
<p> </p><br><br>
来源:https://www.cnblogs.com/xingchong/p/13183162.html
頁:
[1]