Nắm bắt thay thế Node JS để đa luồng


142

Nếu tôi hiểu chính xác thì Node JS không chặn ... vì vậy thay vì chờ phản hồi từ cơ sở dữ liệu hoặc quy trình khác, nó đã chuyển sang một thứ khác và kiểm tra lại sau.

Ngoài ra nó là đơn luồng.

Tất cả điều này có nghĩa là một quy trình Node JS đã cho có thể sử dụng đầy đủ và hiệu quả một lõi CPU nhưng nó sẽ không sử dụng bất kỳ lõi nào khác trên máy, vì trong đó, nó sẽ không bao giờ sử dụng nhiều hơn một lần.

Tất nhiên, điều này có nghĩa là các CPU khác vẫn có thể được sử dụng bởi các quy trình khác cho những thứ như cơ sở dữ liệu SQL hoặc các chương trình con nặng CPU được phân tách có chủ ý khác miễn là chúng là một quy trình riêng biệt.

Ngoài ra, trong trường hợp quy trình Node JS có một vòng lặp vô tận hoặc chức năng chạy dài, thì quá trình đó không còn hữu ích theo bất kỳ cách nào cho đến khi vòng lặp vô tận hoặc chức năng chạy dài bị dừng (hoặc toàn bộ quá trình bị hủy).

Tất cả có đúng không? Tôi có đúng theo cách hiểu của tôi không?


2
"Nút" không phải là luồng đơn. Chỉ có động cơ JS / V8 chạy trong một luồng duy nhất. Phần libuv của NodeJS là đa luồng. Xem NodeJS có thực sự đơn luồng không?
RaelB

Câu trả lời:


87

Khá nhiều chính xác, vâng. Máy chủ node.js có một nhóm luồng nội bộ để nó có thể thực hiện các hoạt động chặn và thông báo cho luồng chính bằng một cuộc gọi lại hoặc sự kiện khi mọi thứ hoàn tất.

Vì vậy, tôi tưởng tượng rằng nó sẽ hạn chế sử dụng một lõi khác cho nhóm luồng, ví dụ nếu bạn thực hiện một hệ thống tệp không chặn thì việc này có thể được thực hiện bằng cách báo cho một luồng từ nhóm luồng để thực hiện đọc và đặt lại cuộc gọi khi nó được thực hiện có nghĩa là việc đọc có thể xảy ra trên một luồng / lõi khác trong khi chương trình node.js chính đang làm một cái gì đó khác.

Nhưng theo quan điểm của node.js, nó hoàn toàn đơn luồng và sẽ không sử dụng trực tiếp nhiều hơn một lõi.


2
Tôi vẫn chưa quen với Node.js và đánh giá cao cuộc thảo luận ở đây. Tôi chỉ muốn chỉ ra rằng việc đưa ra các giả định rằng các cuộc gọi không chặn được hỗ trợ bởi các cuộc gọi chặn theo luồng có lẽ là không khôn ngoan (không phải @jcoder đã đề xuất với mã kiến ​​trúc xung quanh các giả định này). Trong trường hợp này, ngay cả khi IO được xử lý trên một luồng riêng biệt với một cuộc gọi chặn, thì luồng đó về cơ bản sẽ chờ trên IO, do đó, nó sẽ không sử dụng các lõi / CPU khác. Mã cho sức mạnh của các công cụ bạn đang sử dụng và đừng quá lo lắng về các chi tiết cấp thấp (cho đến khi chúng trở thành vấn đề).
wbyoung

vì vậy chúng tôi có thể thực hiện các ưu điểm khác bằng cách sử dụng gọi lại như mã javascript trên frontend
yussan

37

Vâng, tôi muốn nói rằng sự hiểu biết của bạn là hoàn toàn chính xác. Bài viết này ( được lưu trữ ) giải thích lý do đằng sau thiết kế này khá tốt. Đây có lẽ là đoạn quan trọng nhất:

Apache là đa luồng: nó sinh ra một luồng cho mỗi yêu cầu (hoặc quá trình, nó phụ thuộc vào conf). Bạn có thể thấy cách chi phí đó chiếm hết bộ nhớ khi số lượng kết nối đồng thời tăng lên và cần nhiều luồng hơn để phục vụ nhiều máy khách mô phỏng. Nginx và Node.js không phải là đa luồng, bởi vì các luồng và tiến trình mang chi phí bộ nhớ lớn. Chúng là đơn luồng, nhưng dựa trên sự kiện. Điều này giúp loại bỏ chi phí được tạo bởi hàng ngàn luồng / tiến trình bằng cách xử lý nhiều kết nối trong một luồng.


Bài báo là sai. Mặc dù tồn tại một mpm apache đa luồng, nhưng nó không tương thích với tất cả các cấu hình được sử dụng hàng ngày. Apache là đa xử lý, và không đa luồng cho đến bây giờ, và có lẽ sẽ mãi mãi. Tôi thấy nó thật thảm khốc, thao túng ý nghĩa chính xác của thuật ngữ chỉ là một nỗ lực tốt đẹp để che giấu vấn đề, thay vào đó giải quyết nó.
peterh - Phục hồi Monica

1
@peterh Bạn không có ý nghĩa. Bài viết này là hoàn toàn chính xác, nói rằng apache là đa xử lý hoặc đa luồng tùy thuộc vào cấu hình. Trường hợp đa nhóm thậm chí còn tồi tệ hơn khi xử lý nhiều kết nối, đó là lý do duy nhất mà Apache được đề cập ở vị trí đầu tiên. Ngoài ra, mô-đun PHP được sử dụng rất phổ biến là đa luồng của chính nó. Và cuối cùng, trong khi tôi không phải là một chuyên gia về apache, ấn tượng của tôi từ các bài viết khác là MPM worker thực tế được sử dụng rất phổ biến.
Michael Borgwardt

@MichaelBorgwardt Vâng, apache có thể được đa luồng và cũng như đa xử lý, tôi đã không phủ nhận nó. Nhưng php không tương thích với cấu hình đa xử lý, và nếu bạn là một chuyên gia apache, bạn chắc chắn sẽ biết nó. Mô-đun php được sử dụng rất phổ biến không phải là đa luồng. Thông tin của bạn là sai. Tôi đề nghị thử một cấu hình thử nghiệm và bạn sẽ thấy. Đó là một điều thực tế, không phải là vấn đề tranh luận, hãy thử nó và bạn sẽ thấy.
peterh - Phục hồi Monica

27

Ngay cả khi đây là một chủ đề cũ, tôi nghĩ, tôi sẽ chia sẻ với một ý tưởng, làm thế nào để sử dụng nhiều hơn một lõi trong ứng dụng Node.JS. Như Nuray Altin đã đề cập - JXcore có thể làm điều đó.

Ví dụ đơn giản:

var method = function () {
    console.log("this is message from thread no", process.threadId);
};

jxcore.tasks.runOnThread(0, method);
jxcore.tasks.runOnThread(1, method);

// this is message from thread no 1
// this is message from thread no 0

Theo mặc định, có hai luồng (bạn có thể thay đổi nó bằng jxcore.tasks.setThreadCount())

Tất nhiên có nhiều hơn nữa mà bạn có thể làm với các nhiệm vụ. Các tài liệu ở đây .

Vài bài viết về chủ đề đó:


13

Vì câu hỏi này đã hỏi gần 2 năm trước. Mọi thứ đang trở nên khác biệt hoặc có những cách tiếp cận khác nhau cho vấn đề đa luồng trên Node.JS

Theo bài đăng dưới đây, sử dụng tiện ích mở rộng 'tác vụ' đến, một số có thể được hưởng lợi trực tiếp từ các lõi có sẵn khác.

http://oguzbastemur.blogspot.com/2013/12/multithread-nodejs.html


1

Node.js là một ứng dụng đơn luồng, nhưng nó có thể hỗ trợ đồng thời thông qua khái niệm sự kiện và cuộc gọi lại. Dưới đây là video của Philip Roberts giải thích cách các vòng lặp sự kiện hoạt động trong javascript.

Nhấn vào đây để xem video

(Thay vì WebAPI, có API C ++ trong Node.js)


2
Đây phải là một nhận xét
Cherniv
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.