如果我们可以更改线程池使用的线程数,为什么我们需要节点集群?

Why do we need node clusters if we can change the number of threads utilized by the threadpool?

标题基本上说明了一切,当我们可以改变 libuv 线程池使用的线程数时,为什么还要创建节点工作者?

libuv 线程池不用于您的 JavaScript 代码,并且仅用于 Node.js 的 API 的一个子集(尽管它被最常用的 API 之一使用)主要的,fs)。来自 the documentation:

Asynchronous system APIs are used by Node.js whenever possible, but where they do not exist, libuv's threadpool is used to create asynchronous node APIs based on synchronous system APIs. Node.js APIs that use the threadpool are:

  • all fs APIs, other than the file watcher APIs and those that are explicitly synchronous
  • asynchronous crypto APIs such as crypto.pbkdf2(), crypto.scrypt(), crypto.randomBytes(), crypto.randomFill(), crypto.generateKeyPair()
  • dns.lookup()
  • all zlib APIs, other than those that are explicitly synchronous

因此 libuv 线程池的大小有助于大量重叠 fs 和类似的调用,但这不是全部。

如果您有 JavaScript 需要同步执行大量工作的代码,libuv 池将无济于事;该代码在单个线程上运行(除非您启动工作人员)。此外,Node.js 使用同一个线程来检查异步工作的完成(包括 libuv 完成)。来自 event loop page:

The following diagram shows a simplified overview of the event loop's order of operations.

   ┌───────────────────────────┐
┌─>│           timers          │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │     pending callbacks     │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │       idle, prepare       │
│  └─────────────┬─────────────┘      ┌───────────────┐
│  ┌─────────────┴─────────────┐      │   incoming:   │
│  │           poll            │<─────┤  connections, │
│  └─────────────┬─────────────┘      │   data, etc.  │
│  ┌─────────────┴─────────────┐      └───────────────┘
│  │           check           │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
└──┤      close callbacks      │
   └───────────────────────────┘

这样即使不是 运行 您的 JavaScript 代码,一个线程也能完成大量工作。

如果你启动工作线程,它们每个都有自己的事件循环并且可以处理与其工作相关的完成,即使另一个线程正忙于做一些事情 CPU-heavy。

因此,工作线程在任何给定情况下是否有用在很大程度上取决于您的代码在做什么。