Tìm hiểu về Blocking code trong NodeJs
1. Blocking code trong NodeJs là gì ?
Trong lập trình, thuật ngữ “blocking” (chặn) đề cập đến tình huống khi một tác vụ hoặc dòng mã không thể tiếp tục cho đến khi một tác vụ khác hoàn thành. Khi một đoạn mã được gọi là blocking, nghĩa là hệ thống sẽ dừng lại và đợi kết quả của tác vụ đó trước khi tiếp tục thực thi những đoạn mã khác.
Trong Node.js, môi trường hoạt động theo mô hình non-blocking (không chặn), giúp xử lý nhiều yêu cầu cùng lúc mà không làm gián đoạn ứng dụng. Tuy nhiên, đôi khi, bạn vẫn có thể gặp phải các đoạn mã blocking, điều này có thể ảnh hưởng đến hiệu suất và trải nghiệm người dùng.
Blocking code trong NodeJs ám chỉ các thao tác hoặc chức năng mà khi thực thi, chúng sẽ chặn sự tiếp tục của chương trình cho đến khi hoàn tất. Điều này có thể làm giảm hiệu suất của ứng dụng, đặc biệt khi ứng dụng cần xử lý nhiều yêu cầu đồng thời, như trong môi trường máy chủ.
2. Cơ chế hoạt động của Node.js: Non-blocking và Event Loop
Node.js được xây dựng trên mô hình non-blocking (không chặn) và dựa vào event loop để xử lý các tác vụ đồng thời. Điều này có nghĩa là:
- Node.js có thể xử lý rất nhiều yêu cầu mà không cần đợi mỗi yêu cầu hoàn tất trước khi xử lý yêu cầu tiếp theo.
- Node.js sử dụng mô hình asynchronous (bất đồng bộ) và non-blocking để tối ưu hóa việc xử lý các tác vụ I/O (input/output) như đọc/ghi tệp tin, truy vấn cơ sở dữ liệu, hoặc các yêu cầu mạng mà không làm “chặn” chương trình.
Khi blocking code xuất hiện trong ứng dụng Node.js, event loop sẽ bị chặn (blocked), dẫn đến việc Node.js không thể xử lý các yêu cầu tiếp theo cho đến khi tác vụ blocking hoàn tất.

3. Ảnh hưởng của Blocking Code đến Node.js
- Giảm hiệu suất và độ phản hồi: Một trong những đặc điểm nổi bật của Node.js là khả năng xử lý nhiều yêu cầu đồng thời mà không bị “đóng băng” (freeze). Khi gặp phải blocking code, Node.js không thể tiếp tục xử lý các yêu cầu khác cho đến khi thao tác đó hoàn tất, dẫn đến tình trạng chậm trễ và giảm độ phản hồi của ứng dụng.
- Tăng độ trễ của hệ thống: Nếu bạn sử dụng blocking code trong các phần quan trọng của ứng dụng (ví dụ như xử lý yêu cầu HTTP hoặc truy vấn cơ sở dữ liệu), các yêu cầu tiếp theo sẽ phải đợi đến khi các tác vụ blocking hoàn tất. Điều này có thể gây ra hiện tượng nghẽn (bottleneck), làm giảm trải nghiệm người dùng và làm cho hệ thống trở nên kém hiệu quả.
- Giới hạn khả năng mở rộng: Node.js được thiết kế để mở rộng tốt với các ứng dụng mạng hoặc I/O-heavy, có thể xử lý hàng nghìn kết nối đồng thời mà không bị gián đoạn. Tuy nhiên, khi bạn sử dụng blocking code, khả năng mở rộng của ứng dụng sẽ bị ảnh hưởng nghiêm trọng.

4. Cách tránh và xử lý Blocking Code trong Node.js
Để tối ưu hóa ứng dụng Node.js và giữ cho nó không bị gián đoạn bởi blocking code, bạn cần sử dụng các phương thức asynchronous (bất đồng bộ) thay vì đồng bộ.
- Sử dụng các phương thức bất đồng bộ thay vì đồng bộ: Node.js cung cấp các phương thức bất đồng bộ cho các tác vụ I/O như đọc/ghi tệp, truy vấn cơ sở dữ liệu, v.v. Ví dụ:
- Thay vì dùng
fs.readFileSync()
, bạn có thể sử dụng fs.readFile()
để đọc tệp tin bất đồng bộ.
- Thay vì truy vấn cơ sở dữ liệu theo cách đồng bộ, bạn có thể sử dụng các thư viện hoặc phương thức bất đồng bộ (như
db.query()
).
- Sử dụng Promises và async/await: Khi làm việc với các tác vụ bất đồng bộ, bạn có thể sử dụng Promises hoặc async/await để tránh việc sử dụng các callback hàm phức tạp. Điều này giúp mã nguồn trở nên dễ đọc và dễ bảo trì hơn.
- Promises giúp bạn viết mã bất đồng bộ mà không cần phải sử dụng các callback.
- Async/await là cú pháp tiện lợi để làm việc với Promises, giúp mã trở nên dễ hiểu và ngắn gọn hơn.
- Chuyển các tác vụ blocking ra khỏi event loop: Nếu bạn cần phải thực hiện các tác vụ nặng mà không có API bất đồng bộ, bạn có thể chuyển chúng ra khỏi event loop chính của Node.js bằng cách sử dụng Worker Threads hoặc Child Processes:
- Worker Threads: Node.js hỗ trợ
worker_threads
, cho phép bạn chạy mã trong một thread riêng biệt, giúp tránh chặn event loop chính.
- Child Processes: Một cách khác để xử lý các tác vụ blocking là sử dụng child processes để thực hiện tác vụ nặng trong các process riêng biệt.
Việc hiểu và xử lý blocking code trong Node.js là một kỹ năng quan trọng để xây dựng các ứng dụng hiệu quả, đặc biệt khi ứng dụng yêu cầu xử lý hàng nghìn yêu cầu đồng thời. Tránh được blocking code sẽ giúp ứng dụng của bạn hoạt động mượt mà, phản hồi nhanh chóng và dễ dàng mở rộng khi cần thiết.
==========
Xem thêm nhiều kiến thức hữu ích tại đây:
P.A Việt Nam cung cấp đa dạng các dịch vụ Host, Máy Chủ Ảo và Máy Chủ Riêng tương thích với ứng dụng NodeJs:
Cloud Server
Cloud Server Pro
Máy Chủ Riêng
Hosting Nodejs
Tham khảo các ưu đãi: https://www.pavietnam.vn/vn/tin-khuyen-mai/