node.js学习笔记(17) cluster

简介:

从笔记(14)就提及多进程,今日总算可以进入正题。

从v0.6.x开始,Node.js提供了多进程模块cluster,允许创建一组进程来共享同一个socket,并且分担负载压力。


官方文档是这样说的:

A single instance of Node.js runs in a single thread. To take advantage of multi-core systems the user will sometimes want to launch a cluster of Node.js processes to handle the load.

The cluster module allows you to easily create child processes that all share server ports.

单个node.js实例的运行是单线程的。用户有时候想运行一组进程来运行node.js实例以提高多核系统的性能。

cluster模块让你轻松创建可以共享服务端口的子进程。


那么试试先,用cluster共享一个http服务。

cluster-1.js:

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
    // Fork workers.
    for (var i = 0; i < numCPUs; i++) {
        cluster.fork();
    }

    cluster.on('exit', function(worker, code, signal){
        console.log('worker ' + worker.process.pid +' died');
    });
} else {
    // Workers can share any TCP connection
    // In this case it is an HTTP server
    http.createServer(function(req, res){
        res.writeHead(200);
        res.end('hello world, child-process:'+cluster.worker.id+'\n');
    }).listen(8000);
}


开启服务:


lee@mypc ~/works/nodejs/study17 $ node cluster-1.js


http访问效果:

lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:2
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:3
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:1
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:4
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:2
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:3
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:1
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:4
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:2
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:3
显然,虽然每次http访问都能得到结果“hello world”,但却并不是同一个进程。

并且我们可以看到cluster实现了的负载均衡,cluster会把请求依次分配给子进程2-3-1-4-2-3-1-4...........这是一个罗宾环。


cluster默认使用round-robin来实现负载均衡。也可以不使用round-robin。


lee@mypc ~/works/nodejs/study17 $ env NODE_CLUSTER_SCHED_POLICY="none" node cluster-1.js


这个时候,http访问的效果变成了随机:


lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:4
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:1
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:1
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:1
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:1
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:4
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:3
lee@mypc ~ $ curl http://localhost:8000
hello world, child-process:1




cluster是如何工作的?


cluster的工作进程是通过child_process.fork()来创建的,所以它们与父进程间可以进行通讯。

可以从源码中找到child_process.fork()的实现。

源码片段:

'use strict';

const EventEmitter = require('events');
const assert = require('assert');
const dgram = require('dgram');
const fork = require('child_process').fork;

......
  cluster.fork = function(env) {
    cluster.setupMaster();
    const id = ++ids;
    const workerProcess = createWorkerProcess(id, env);
    const worker = new Worker({
      id: id,
      process: workerProcess
    });
......

  function createWorkerProcess(id, env) {
    ......
    return fork(cluster.settings.exec, cluster.settings.args, {
      env: workerEnv,
      silent: cluster.settings.silent,
      execArgv: execArgv,
      gid: cluster.settings.gid,
      uid: cluster.settings.uid
    });
  }


目录
相关文章
|
18天前
|
Web App开发 前端开发 JavaScript
HTML/CSS/JS学习笔记 Day3(HTML--网页标签 下)
HTML/CSS/JS学习笔记 Day3(HTML--网页标签 下)
|
30天前
|
Java jenkins Shell
jenkins学习笔记之五:Maven、Ant、Gradl、Node构建工具集成
jenkins学习笔记之五:Maven、Ant、Gradl、Node构建工具集成
|
2月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的云的学习笔记系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的云的学习笔记系统附带文章源码部署视频讲解等
32 0
|
4月前
|
移动开发 JavaScript 前端开发
webgl学习笔记3_javascript的HTML DOM
webgl学习笔记3_javascript的HTML DOM
52 0
webgl学习笔记3_javascript的HTML DOM
|
4月前
|
JavaScript 前端开发 Java
webgl学习笔记2_javascript基础快速学习
webgl学习笔记2_javascript基础快速学习
41 0
|
4月前
|
前端开发 JavaScript API
JavaScript学习笔记(一)promise与async
JavaScript学习笔记(一)promise与async
|
4月前
|
存储 JavaScript
【ES6系列第二篇】适用JS初学者的Set对象和Map对象学习笔记
【ES6系列第二篇】适用JS初学者的Set对象和Map对象学习笔记
45 0
|
11月前
|
存储 Kubernetes 调度
什么是 Kubernetes cluster 的 Node affinity
什么是 Kubernetes cluster 的 Node affinity
|
10月前
|
存储 JavaScript 前端开发
【js】函数概述学习笔记(8)
【js】函数概述学习笔记(8)
35 0
|
10月前
|
存储 JavaScript
【js】数组学习笔记(7-2)
【js】数组学习笔记(7-2)
57 0