Worker Threads trong Node.js là một cơ chế giúp thực hiện đa luồng (multi-threading), cho phép chạy các tác vụ nặng về CPU mà không ảnh hưởng đến hiệu suất của luồng chính (Event Loop).
💡 Tại sao cần Worker Threads?
- Node.js vốn là single-threaded, tức là chỉ có một luồng thực thi chính.
- Khi gặp tác vụ nặng về tính toán, luồng chính sẽ bị đóng băng, làm chậm cả ứng dụng.
- Worker Threads giúp chạy các tác vụ này trên luồng riêng, không ảnh hưởng đến hiệu suất tổng thể.
📌 Ứng dụng thực tế:
✅ Xử lý ảnh, video, âm thanh (Sharp, FFmpeg, Puppeteer)
✅ Mã hóa / Giải mã dữ liệu (AES, RSA, zlib)
✅ AI / Machine Learning (TensorFlow.js, OpenCV)
✅ Xử lý dữ liệu lớn, tính toán phức tạp
📌 Lợi ích:
✔ Tăng tốc xử lý bằng cách chạy nhiều Worker song song
✔ Không làm chậm Event Loop, giúp ứng dụng phản hồi nhanh hơn
✔ Dễ dàng mở rộng, phù hợp với ứng dụng có nhiều tác vụ CPU nặng
🔥 1. Worker Threads là gì?
Worker Threads trong Node.js là một cách để chạy mã JavaScript đa luồng (multi-threading).
Mặc dù Node.js sử dụng một luồng chính (single-threaded), nhưng nhờ worker_threads
, bạn có thể chạy các tác vụ nặng trên các luồng riêng mà không làm ảnh hưởng đến hiệu suất của chương trình chính.
📌 Ứng dụng của Worker Threads:
✅ Xử lý ảnh, video, âm thanh (ví dụ: sharp
, trim-image
)
✅ Nén, mã hóa dữ liệu (ví dụ: zlib
, crypto
)
✅ Tính toán nặng như AI, Machine Learning, Blockchain
✅ Xử lý dữ liệu lớn (big data)
🔥 2. Cách tạo một Worker Thread cơ bản
📌 Ví dụ: Tạo một Worker thực hiện tính tổng từ 1 đến N
🔹 Bước 1: Tạo file chính main.js
const { Worker } = require('worker_threads');
function runWorker(n) {
return new Promise((resolve, reject) => {
const worker = new Worker('./worker.js', { workerData: { num: n } });
worker.on('message', (result) => resolve(result)); // Nhận kết quả từ Worker
worker.on('error', reject);
worker.on('exit', (code) => {
if (code !== 0) reject(new Error(`Worker exited with code ${code}`));
});
});
}
async function main() {
const result = await runWorker(1000000);
console.log(`✅ Tổng từ 1 đến 1000000 là: ${result}`);
}
main();
🔹 Bước 2: Tạo file Worker worker.js
const { parentPort, workerData } = require('worker_threads');
function sum(n) {
let total = 0;
for (let i = 1; i <= n; i++) total += i;
return total;
}
const result = sum(workerData.num);
parentPort.postMessage(result); // Gửi kết quả về `main.js`
👉 Chạy lệnh:
node main.js
📌 Kết quả:
✅ Tổng từ 1 đến 1000000 là: 500000500000
💡 Lợi ích:
- Chương trình chính không bị chậm, vì tính toán chạy trên luồng riêng.
- Dễ dàng mở rộng để xử lý nhiều tác vụ song song.
🔥 3. Chạy nhiều Worker đồng thời (Multi-Threading)
📌 Ví dụ: Tạo nhiều Worker để chạy cùng lúc
🔹 main.js
(Chạy 3 Worker song song)
const { Worker } = require('worker_threads');
const workers = [];
const numbers = [100000, 500000, 1000000];
for (const num of numbers) {
const worker = new Worker('./worker.js', { workerData: { num } });
worker.on('message', (result) => console.log(`✅ Tổng từ 1 đến ${num} là: ${result}`));
worker.on('error', (err) => console.error(err));
worker.on('exit', () => console.log(`Worker cho ${num} đã hoàn thành.`));
workers.push(worker);
}
📌 Kết quả:
✅ Tổng từ 1 đến 100000 là: 5000050000
✅ Tổng từ 1 đến 500000 là: 125000250000
✅ Tổng từ 1 đến 1000000 là: 500000500000
Worker cho 100000 đã hoàn thành.
Worker cho 500000 đã hoàn thành.
Worker cho 1000000 đã hoàn thành.
💡 Lợi ích:
- Tận dụng tối đa CPU bằng cách chạy nhiều Worker đồng thời.
- Tăng tốc đáng kể khi xử lý nhiều tác vụ nặng.
🔥 4. Quản lý Worker bằng hàng đợi (Queue)
📌 Vấn đề: Nếu tạo quá nhiều Worker cùng lúc, có thể gây quá tải hệ thống.
📌 Giải pháp: Sử dụng hàng đợi (Queue) để giới hạn số Worker hoạt động đồng thời.
🔹 main.js
(Hàng đợi giới hạn 2 Worker cùng lúc)
const { Worker } = require('worker_threads');
const pLimit = require('p-limit');
const MAX_WORKERS = 2; // Giới hạn số Worker đồng thời
const numbers = [100000, 500000, 1000000, 1500000, 2000000];
const limit = pLimit(MAX_WORKERS);
async function runWorker(n) {
return new Promise((resolve, reject) => {
const worker = new Worker('./worker.js', { workerData: { num: n } });
worker.on('message', resolve);
worker.on('error', reject);
worker.on('exit', () => console.log(`Worker cho ${n} đã hoàn thành.`));
});
}
async function processNumbers() {
const tasks = numbers.map(n => limit(() => runWorker(n)));
const results = await Promise.all(tasks);
console.log(`Tổng kết quả: ${results}`);
}
processNumbers();
📌 Kết quả:
- Luôn chỉ có tối đa 2 Worker chạy cùng lúc, giúp tiết kiệm tài nguyên hệ thống.
- Khi 1 Worker hoàn thành, ảnh tiếp theo sẽ được xử lý ngay lập tức.
🔥 5. Khi nào KHÔNG nên dùng Worker Threads?
❌ Không cần dùng Worker Threads nếu công việc:
- Là I/O-based (đọc ghi file, gọi API, database). Hãy dùng async/await hoặc streaming thay vì Worker Threads.
- Chỉ xử lý nhanh (dưới 100ms). Không cần tạo Worker vì tốn thêm chi phí khởi tạo.
✅ Nên dùng Worker Threads cho CPU-heavy tasks như:
✔ Xử lý ảnh (Sharp, Puppeteer)
✔ Mã hóa / Giải mã dữ liệu
✔ AI / Machine Learning
✔ Xử lý dữ liệu lớn
🎯 Tóm tắt
✔ Worker Threads giúp tăng tốc xử lý tác vụ nặng mà không làm chậm luồng chính.
✔ Dùng hàng đợi (Queue) để tránh quá tải hệ thống.
✔ Không cần Worker Threads cho các tác vụ I/O-based, hãy dùng async/await.
🚀 Giờ thì bạn có thể tối ưu ứng dụng Node.js bằng Worker Threads một cách chuyên nghiệp!