
Chào các chiến thần Gen Z! Hôm nay, anh Creyt sẽ cùng các em "mổ xẻ" một khái niệm nghe qua thì khô khan, nhưng lại cực kỳ quyền năng trong thế giới Node.js: os.cpus(). Hãy tưởng tượng thế này, máy tính của các em không chỉ là một cỗ máy đơn lẻ, mà nó giống như một nhà hàng lớn, và mỗi CPU core (lõi xử lý) chính là một "đầu bếp" chuyên nghiệp.
1. os.cpus() là gì và để làm gì? – "Đếm Đầu Bếp" và "Xem Thực Đơn"
Thằng os.cpus() này, nó nằm trong module os (operating system – hệ điều hành) của Node.js, đúng như tên gọi. Nhiệm vụ của nó "siêu đơn giản": nó sẽ trả về cho các em một array (mảng) các object (đối tượng), mà mỗi object đó đại diện cho một "đầu bếp" – tức là một CPU core – trong máy tính của các em. Không chỉ đếm số lượng, nó còn cho biết "lý lịch trích ngang" của từng đầu bếp nữa chứ!
Để làm gì ư? À, đây mới là phần hay nè. Khi các em muốn tối ưu hiệu năng của ứng dụng Node.js, đặc biệt là những ứng dụng phải xử lý nhiều tác vụ nặng (kiểu như tính toán phức tạp, xử lý ảnh/video, mã hóa/giải mã), thì việc biết được mình có bao nhiêu "đầu bếp" là cực kỳ quan trọng. Node.js vốn dĩ là single-threaded (đơn luồng) cho JavaScript runtime, nhưng với os.cpus(), các em có thể "đánh lừa" nó, biến nó thành một "nhà hàng đa đầu bếp" bằng cách tận dụng module cluster để phân chia công việc.
Nói cách khác, nó giúp các em:
- Hiểu sức mạnh thật sự của server: "À, server mình có 8 core, vậy là có 8 đầu bếp khỏe mạnh, mình có thể giao nhiều việc hơn."
- Tối ưu hiệu năng: Phân chia công việc cho các "đầu bếp" khác nhau để xử lý song song, tránh tình trạng một "đầu bếp" làm việc quá tải còn những người khác ngồi chơi xơi nước.
- Scale ứng dụng: Chuẩn bị cho việc ứng dụng của các em "lên đời" và cần xử lý lượng request khổng lồ.
2. Code Ví Dụ Minh Hoạ – "Nhờ Thằng Quản Lý Báo Cáo Số Lượng Đầu Bếp"
Giờ thì chúng ta "xắn tay áo" vào code thôi. Anh Creyt đảm bảo code này dễ hiểu hơn cả việc order trà sữa nữa.
const os = require('os');
// Lấy thông tin tất cả các CPU core
const cpus = os.cpus();
console.log(`
--- Thông tin CPU của bạn ---
`);
console.log(`Bạn có tổng cộng ${cpus.length} "đầu bếp" (CPU cores) đang hoạt động.`);
// In ra thông tin chi tiết của từng "đầu bếp"
cpus.forEach((cpu, index) => {
console.log(`
Đầu bếp số ${index + 1}:`);
console.log(` - Tên hiệu: ${cpu.model}`);
console.log(` - Tốc độ: ${cpu.speed / 1000} GHz`); // Tốc độ tính bằng MHz, chia 1000 để ra GHz
console.log(` - Thời gian hoạt động (ms):`);
console.log(` - User (làm việc): ${cpu.times.user}`);
console.log(` - Nice (ưu tiên thấp): ${cpu.times.nice}`);
console.log(` - Sys (hệ thống): ${cpu.times.sys}`);
console.log(` - Idle (nghỉ ngơi): ${cpu.times.idle}`);
console.log(` - Irq (ngắt): ${cpu.times.irq}`);
});
// Một ví dụ tính toán đơn giản về tổng thời gian CPU đã làm việc và nghỉ ngơi
const totalIdleTime = cpus.reduce((acc, cpu) => acc + cpu.times.idle, 0);
const totalBusyTime = cpus.reduce((acc, cpu) => acc + cpu.times.user + cpu.times.nice + cpu.times.sys + cpu.times.irq, 0);
const totalCPUTime = totalIdleTime + totalBusyTime;
console.log(`
--- Tình hình làm việc chung của các "đầu bếp" ---
`);
console.log(`Tổng thời gian nghỉ ngơi: ${totalIdleTime} ms`);
console.log(`Tổng thời gian bận rộn: ${totalBusyTime} ms`);
console.log(`Tỷ lệ bận rộn (ước tính): ${((totalBusyTime / totalCPUTime) * 100).toFixed(2)}%`);
Khi chạy đoạn code này, các em sẽ thấy một "báo cáo" chi tiết về tất cả các CPU core trên máy của mình, từ tên model, tốc độ, cho đến thời gian mà nó dành cho các tác vụ khác nhau (user, system, idle...). Cái times object này cực kỳ hay ho, nó cho các em biết "đầu bếp" nào đang "rảnh rỗi" hay "bận rộn" đến mức nào.

3. Mẹo Vặt & Best Practices – "Bí Kíp Của Thằng Chủ Nhà Hàng Khôn Ngoan"
- Đừng chỉ đếm, hãy hiểu: Số lượng core quan trọng, nhưng thông tin
modelvàspeedcũng không kém. Một con CPU đời mới 4 core có thể mạnh hơn con CPU đời tống 8 core đấy. Luôn nhìn vào bức tranh tổng thể. - Kết hợp với
clustermodule: Đây là "cặp bài trùng" huyền thoại.os.cpus().lengththường được dùng để xác định số lượng worker processes (tiến trình con) mà moduleclusternên tạo ra. Ví dụ, nếu có 8 core, các em có thể tạo 8 worker process để mỗi "đầu bếp" đảm nhận một tiến trình, tối ưu hóa việc xử lý request.const cluster = require('cluster'); const os = require('os'); const numCPUs = os.cpus().length; if (cluster.isMaster) { console.log(`Master ${process.pid} is running. Spawning ${numCPUs} workers.`); for (let i = 0; i < numCPUs; i++) { cluster.fork(); // Tạo worker process cho mỗi CPU core } cluster.on('exit', (worker, code, signal) => { console.log(`Worker ${worker.process.pid} died. Forking a new one...`); cluster.fork(); // Tự động khởi tạo lại worker nếu có lỗi }); } else { // Worker processes có thể chạy server HTTP hoặc các tác vụ nặng console.log(`Worker ${process.pid} started.`); // Ví dụ: app.listen(8000); } - Theo dõi "sức khỏe" CPU: Thông tin
timeslà vàng đấy. Các em có thể dùng nó để xây dựng các công cụ giám sát, cảnh báo khi CPU quá tải. Một "đầu bếp" làm việc 100% thời gian không nghỉ là dấu hiệu của một server đang "nghẹt thở". - Tránh "lạm dụng": Không phải lúc nào cũng cần tạo ra số worker process bằng số lượng CPU core. Nếu ứng dụng của em chủ yếu là I/O-bound (chờ đợi dữ liệu từ database, network) chứ không phải CPU-bound, thì việc tạo quá nhiều worker đôi khi còn phản tác dụng do overhead quản lý tiến trình. Hãy test và điều chỉnh cho phù hợp.
4. Ứng Dụng Thực Tế – "Nhà Hàng Nào Đang Dùng Kỹ Thuật Này?"
Các em có thể đã và đang sử dụng những dịch vụ áp dụng nguyên lý này mà không hề hay biết:
- Netflix, YouTube: Khi các em upload một video, quá trình mã hóa (encoding) video đó cần rất nhiều CPU. Các hệ thống này sẽ chia nhỏ video ra, và dùng nhiều "đầu bếp" (CPU cores/workers) để xử lý các phần khác nhau của video song song, giúp quá trình nhanh hơn gấp nhiều lần.
- Các nền tảng thương mại điện tử lớn (Shopee, Lazada): Để xử lý hàng triệu request mỗi giây, các hệ thống backend của họ phải được tối ưu hóa để tận dụng tối đa tài nguyên server, trong đó có việc phân phối tải lên các CPU core khác nhau.
- CI/CD Pipelines (ví dụ: Jenkins, GitLab CI): Khi chạy các bài test hoặc build dự án, các hệ thống này thường phân phối các job nhỏ hơn tới các agent (máy tính) khác nhau, và trên mỗi agent đó, họ lại tận dụng đa luồng/đa tiến trình để chạy test song song, giảm thời gian chờ đợi.
5. Thử Nghiệm & Hướng Dẫn Sử Dụng – "Trải Nghiệm Đau Thương Của Anh Creyt"
Anh Creyt nhớ hồi mới "vào nghề", cũng "ngây thơ" lắm. Cứ nghĩ Node.js là single-threaded thì cả thế giới chỉ chạy được một luồng. Thế là viết một cái API tính toán chuỗi Fibonacci cực dài, chạy trên một con server 4 core. Kết quả là gì? Một core làm việc "bạc mặt" 100%, 3 core còn lại "ngồi chơi xơi nước", và request thì xếp hàng dài cổ chờ xử lý. Cái API chậm như rùa bò!
Sau này, anh mới "ngộ" ra chân lý os.cpus() và cluster. Anh đã thử nghiệm bằng cách sử dụng os.cpus().length để tạo ra số lượng worker processes bằng số core CPU. Kết quả là "một trời một vực"! Thời gian xử lý request giảm đi đáng kể, server cũng "thở phào nhẹ nhõm" hơn vì công việc được chia đều cho các "đầu bếp".
Vậy nên dùng os.cpus() trong những trường hợp nào?
- Khi ứng dụng của em là CPU-bound: Tức là ứng dụng của em thực hiện nhiều phép tính toán phức tạp, xử lý dữ liệu nặng, mã hóa/giải mã, nén/giải nén...
- Xây dựng các microservices hoặc API gateway: Để đảm bảo khả năng chịu tải và mở rộng khi có nhiều yêu cầu đồng thời.
- Phát triển các công cụ giám sát hiệu năng: Để thu thập thông tin về CPU usage và đưa ra cảnh báo.
- Khi muốn tối ưu hóa việc sử dụng tài nguyên trên một server vật lý: Thay vì chỉ chạy một tiến trình Node.js duy nhất, hãy tận dụng toàn bộ số core mà server có.
- Dùng kèm với
worker_threads(từ Node.js 10.5.0): Nếu các em muốn thực hiện các tác vụ CPU-bound trong cùng một tiến trình nhưng trên các luồng riêng biệt,worker_threadslà một lựa chọn khác, vàos.cpus().lengthvẫn có thể giúp các em quyết định số lượng worker threads nên tạo ra.
Nhớ nhé, các em Gen Z! Trong lập trình, hiểu rõ tài nguyên mình đang có trong tay là chìa khóa để xây dựng những ứng dụng "bất khả chiến bại". os.cpus() chính là "bản đồ kho báu" giúp các em khám phá sức mạnh tiềm ẩn của cỗ máy của mình. Cứ thực hành đi, rồi các em sẽ thấy nó "ngon" như thế nào!
Thuộc Series: Nodejs
Bài giảng này được tự động xuất bản ngẫu nhiên từ thư viện kiến thức. Đừng quên đón xem các Từ khoá Hướng Dẫn tiếp theo nhé!