Chúng ta đều biết rằng engine V8 là một engine đơn luồng (single-thread), tức là ở đây không thể chạy song song nhiều công việc cùng một lúc được, cơ chế bất đồng bộ (Asynchronous) của Node chẳng qua cũng chỉ là để chống server bị blocked thôi chứ thực chất các công việc vấn theo thứ tự trước-sau. Trong bài Tăng hiệu suất server chúng ta cũng đã tìm hiểu một cách để chạy nhiều server đó là tạo nhiều instance chạy trên nhiều cổng khác nhau, tuy nhiên như thế sẽ rất bất tiện và đem lại trải nghiệm không tốt cho người dùng, chẳng ai lại muốn gõ địa chỉ website rồi thêm số cổng đằng sau cả.
Do đó trong phần này chúng ta sẽ tìm hiểu một cách khác để tăng hiệu suất của server là chạy nhiều tiến trình để tận dụng các core của CPU. Kể từ phiên bản Node 0.8 trở lên, Node cho ra đời module cluster
cho phép lập trình viên “tạo nhiều tiến trình mạng sử dụng chung cổng”, các tiến trình này đều nằm trên một máy, module này không cho phép chúng ta thao tác với cùng tiến trình trên các máy khác.
Module cluster
cung cấp các hàm API ở cấp độ rất thấp, do đó bạn có thể làm rất nhiều trò với CPU, và cũng vì thế mà module này rất khó dùng nếu bạn không có nhiều kiến thức về cách hệ điều hành quản lý tiến trình, bộ nhớ… Tuy nhiên trên thực tế thì chúng ta cũng không nên quan tâm đến các thứ cấp thấp đó mà chỉ nên tập trung phát triển các tính năng của website, do đó chúng ta sẽ sử dụng các module ở cấp cao hơn để đơn giản hóa việc sử dụng, ở đây chúng ta sẽ dùng module workforce
.
Cài đặt
Đầu tiên chúng ta khai báo module này trong file package.json:
{ "name": "notes", "version": "0.0.0", "private": true, "scripts": { "start": "node ./bin/www" }, "dependencies": { "body-parser": "~1.15.1", "cookie-parser": "~1.4.3", "debug": "~2.2.0", "ejs": "~2.4.1", "express": "~4.13.4", "morgan": "~1.7.0", "serve-favicon": "~2.3.0", "async": "*", "sqlite3": "*", "mongoose": "*", "sequelize": "*", "connect-flash": "*", "passport": "*", "passport-local": "*", "express-session": "*", "workforce": "*" } }
Sau đó chạy lệnh npm install
để cài đặt.
Tiếp theo chúng ta tạo file workforce.js
trong thư mục gốc của project với đoạn code sau:
var workforce = require('workforce'); var manager = workforce('./app.js'); manager.set('workers', 4); manager.set('title', 'Notes'); manager.set('restart threshold', '10s'); manager.set('exit timeout', '5s'); manager.listen(process.env.PORT || 3000);
Trong đoạn code trên chúng ta tạo một đối tượng workforce
và thiết lập một số thông số cần thiết. Trong đó:
workers
là số tiến trình tối đa được mở, thường thì con số này nên bằng số core của CPUtitle
sẽ được thêm trước vào tên mỗi tiến trình được tạo rarestart threshold
là thời gian một tiến trình được phép tồn tại, sau khi hết thời gian đó thì workforce sẽ hủy tiến trình này và tạo lại một tiến trình mới thay thếexit timeout
là thời gian chờ sau khi có lệnh hủy một tiến trình
Trong file app.js,
ở cuối file có dòng:
module.exports = app;
Dòng này sẽ cho phép đối tượng app có thể được gọi từ các module khác. Nếu của bạn không có thì bạn thêm dòng này vào.
Vậy là xong, bây giờ chúng ta có thể chạy nhiều tiến trình server được rồi, và chúng ta sẽ không dùng lệnh npm start
nữa mà dùng lệnh:
C:\NodeJS\notes>node workforce.js
Bạn có thể mở Task Manager trên Windows để xác nhận.
Sở dĩ ở đây có 5 tiến trình là vì tiến trình đầu tiên là tiến trình chạy file workfoce.js,
từ tiến trình này 4 tiến trình app.js
được tạo ra.