NodeJS cơ bản cho người mới bắt đầu

Bài 18: NodeJS - Scaling Ứng dụng

NodeJs là nền tảng đơn luồng, nhưng được sử dụng để lưu trữ mô hính sự kiện để xử lý đồng thời. NodeJs tạo điều kiện để khởi tạo các chuỗi tiến trình con để thúc đẩy xử lý song song trong hệ thống CPU đa lõi
Các chuỗi tiến trình con có 3 stream chính child.stdinchild.stdout, và child.stderr mà có thể được chia sẻ với stream stdio của tiến trình cha
Ngoài ra, node còn cung cấp child_process , trong đó có ba cách chính sau đây để tạo quy trình con:
  • exec − phương thức child_process.exec chạy lệnh trong shell / console và buffer đầu ra.
  • spawn - khởi tạo child_process.spawn là một quá trình được lấy từ command
  • fork - phương thức child_process.for là trường hợp đặc biệt của spawn() để tạo tiến trình con

1. Phương thức exec():

Phương thức child_process.exec chạy các lệnh từ command trong Shell và buffer đầu ra, nó có dạng như sau :
child_process.exec(command[, options], callback)
Các tham số :
  1. command (String): chạy lệnh cmd , các đối số được phân tách bởi khoảng trắng
  2. options(Object): Bao gồm một hoặc nhiều option sau :
  • cwd (String) làm việc trực tiếp với tiến trình con
  • env (Object) Các cặp key-value
  • shell (String) để thực thi các lệnh (mặc định: '/bin/sh' on UNIX, 'cmd.exe' trên Windows, shell nên được hiểu -c chuyển sang UNIX hoặc /s /c ở Windows. Trên Windows, cmd parsing nên tương thích cmd.exe.)
  • timeout (Number) (mặc định: 0)
  • maxBuffer (Number) (mặc định: 200*1024)
  • killSignal (String) (mặc định: 'SIGTERM')
  • uid (Number) nhận biết user trong quá trình chạy
  • gid (Number) nhận biết group trong quá trình chạy
callback hàm lấy 3 đối số errorstdout, và stderr được gọi khi tiến trình kết thúc.
Hàm exec() trả về buffer với kích thước lớn nhất và đợi đến khi tiến trình kết thúc sẽ cố gắng trả về tất cả các dữ liệu trong bộ đệm cùng 1 lúc

Ví dụ

Tạo 2 file js bao gồm : support.js và master.js
support.js : 
console.log("Child Process " + process.argv[2] + " executed." );
master.js :
const fs = require('fs');
const child_process = require('child_process');

for(var i=0; i<3; i++) {
   var workerProcess = child_process.exec('node support.js '+i,function 
      (error, stdout, stderr) {
      
      if (error) {
         console.log(error.stack);
         console.log('Error code: '+error.code);
         console.log('Signal received: '+error.signal);
      }
      console.log('stdout: ' + stdout);
      console.log('stderr: ' + stderr);
   });

   workerProcess.on('exit', function (code) {
      console.log('Child process exited with exit code '+code);
   });
}
Bây giờ hãy thử chạy file master.js :
$ node master.js
Kiểm tra đầu ra,server bắt đầu chạy như sau :
Child process exited with exit code 0
stdout: Child Process 1 executed.

stderr:
Child process exited with exit code 0
stdout: Child Process 0 executed.

stderr:
Child process exited with exit code 0
stdout: Child Process 2 executed.

2. Phương thức spawn() :

phương thức child_process.spawn khởi chạy một quy trình mới với một lệnh nhất định. Nó như sau : 
child_process.spawn(command[, args][, options])
Các tham số được sử dụng :
  • command (String) chạy lệnh
  • args (Array) Danh sách chuỗi các tham số
  • options (Object) có thể bao gồm một hoặc nhiều tùy chọn sau:cwd (String) Thư mục làm việc hiện tại của tiến trình con.env (Object) Các cặp khóa-giá trịstdio (Array) Cấu hình stdio của String Child.customFds (Array) Bộ mô tả tệp không được chấp nhận để con sử dụng cho stdio.detached (Boolean) lớp con sẽ chỉ định tiến trìnhuid (Number)Đặt danh tính người dùng của quy trình.gid (Number) Đặt danh tính group của quy trình.
Phương thức spawn () trả về các luồng (stdout & stderr) và nó sẽ được sử dụng khi quá trình trả về một lượng lớn dữ liệu. spawn () bắt đầu nhận phản hồi ngay khi tiến trình bắt đầu thực thi.

 Ví dụ : 

support.js
console.log("Child Process " + process.argv[2] + " executed." );
master.js:
const fs = require('fs');
const child_process = require('child_process');
 
for(var i = 0; i<3; i++) {
   var workerProcess = child_process.spawn('node', ['support.js', i]);

   workerProcess.stdout.on('data', function (data) {
      console.log('stdout: ' + data);
   });

   workerProcess.stderr.on('data', function (data) {
      console.log('stderr: ' + data);
   });

   workerProcess.on('close', function (code) {
      console.log('child process exited with code ' + code);
   });
}
chạy lệnh :
$ node master.js
Kết quả như sau :
stdout: Child Process 0 executed.

child process exited with code 0
stdout: Child Process 1 executed.

stdout: Child Process 2 executed.

child process exited with code 0
child process exited with code 0

3. Phương thức fork():

Phương thức child_process.fork là một trường hợp đặc biệt của spawn () để tạo các tiến trình Node:
child_process.fork(modulePath[, args][, options])
Tham số được sử dụng :
  • modulePath (String) Các mô-đun để chạy trong lớp con.
  • args (Array) danh sách chuỗi các đối số 
  • options (Object) có thể bao gồm một hoặc nhiều tùy chọn sau:cwd (String) Thư mục làm việc hiện tại của tiến trình con.env (Object) các cặp key-valueexecPath (String) được sử dụng để tạo tiến trình con.execArgv (Array) Danh sách các đối số chuỗi được chuyển đến tệp thực thi (Mặc định: process.execArgv).silent (Boolean) nếu đúng, stdin, stdout và stderr của con sẽ được chuyển đến cha mẹ, nếu không chúng sẽ được thừa kế từ cha mẹ, hãy xem các tùy chọn "pipe" và "inherit" cho stdio của spawn () để biết thêm chi tiết (mặc định là sai).uid (Number) Đặt danh tính người dùng của quy trình.gid (Number) Đặt danh tính nhóm của quy trình.
Phương thức fork trả về một đối tượng có kênh giao tiếp tích hợp bên cạnh việc có tất cả các phương thức trong một phiên bản ChildProcess bình thường

Ví dụ :

support.js
console.log("Child Process " + process.argv[2] + " executed." );
master.js
const fs = require('fs');
const child_process = require('child_process');
 
for(var i=0; i<3; i++) {
   var worker_process = child_process.fork("support.js", [i]);	

   worker_process.on('close', function (code) {
      console.log('child process exited with code ' + code);
   });
}
Chạy dòng lệnh sau :
$ node master.js
Kết quả như sau :
Child Process 0 executed.
Child Process 1 executed.
Child Process 2 executed.
child process exited with code 0
child process exited with code 0
child process exited with code 0