Node.js
scalability

Motivation

how to avoid service being slowly when server is doing heavy loading work?

Motivation

how to avoid service being slowly when server is doing heavy loading work?

History of
Web Service Model

#1

#2

#3

Process VS Thread

C10K Problem

1. 進程線程多

2. 數據拷貝頻繁(緩存I/O、內核將數據拷貝到用戶進程空間、阻塞)

3.  進程/線程上下文切換消耗大, 導致操作系統崩潰

在同時連接到服務器的客戶端數量超過10000 個的環境中,即便硬件性能足夠, 依然無法正常提供服務

C10K Problem Solution

C10K Problem Solution

Mutuple Process

Architecture

In Node.js

Create Child Process

  1. spawn
  2. exec
  3. execFile
  4. fork

Create Child Process

  1. spawn
  2. exec
  3. execFile
  4. fork
var cp = require('child_process');
cp.spawn('node', ['worker.js']);
cp.exec('node worker.js', function (err, stdout, stderr) {
  // some code
});
cp.execFile('worker.js', function (err, stdour, stderr) {
  // some code
});

cp.fork('./worker.js');

Communication

Ex: WebWorker API

var worker = new Worker('worker.js');
worker.onmessage = function (event) {
  document.getElementById('result').textContent = event.data;
}


// worker.js
var n = 1;
search: while(true) {
  n += 1;
  // do something

  // if done
  postMessage(n);
}

Communication

In Node.js

// parent.js
var cp = require('child_process');
var n = cp.fork(__dirname + '/sub.js');

n.on('message', function (m) {
  console.log('PARENT got message:', m);
});

n.send({hello: 'world'});

// sub.js
process.on('message', function(m) {
  console.log('CHILD got message:', m);
});

process.send({foo: 'bar'});

Communication

Internal Process Communication

  1. semaphore
  2. message
  3. queue 
  4. pipe
  5. mutex
  6. share memory

Control

var http = require('http');
http.createServer(function(req, res) {
 res.writeHead(200, {'Content-Type': 'text/plain');
 res.end('Hello World\n');
}).listen(8888, '127.0.0.1');

Control Code

child.send(message, [sendHandle]);

Control Code

Control Code

Control Code

{
  cmd: 'NODE_MODULE',
  type: 'net.Server',
  msg: message,
}

Stability in Node.js

  • Automatic Reboot
  • Round-Robin

Node.js Cluster

Cluster Example

var cluster = require('cluster');

cluster.setupMaster({
  exec: "worker.js"
});

var cpus = require('os').cpus();
for (var i = 0; i < cpus.length; i++) {
  cluster.fork();
}

Thank you

Q&A

Node.js scalability

By Stanney Yen

Node.js scalability

  • 275