Bha*_*vin 4 multithreading event-loop threadpool node.js
要求是每秒1000个并发请求和每个请求的数据库查询等IO操作。由于 nodejs 在事件循环上工作,它将 IO 操作分配给线程池,但线程池默认大小为 4,因此同时最多 4 个线程(IO 操作)可以工作,其余必须在队列中等待。一旦任何线程完成执行,它们就可以进行处理。
查询 1 - 我们可以根据需要将线程池大小增加到 N 数,它会提高性能还是会降低性能?
查询 2 - 我们如何在 nodejs 中实现上述要求?
查询 3 - Nodejs 是此要求或其他建议(例如 golang)的空闲选择
node.js 上的网络 I/O 操作在主线程上运行。
是的,除了主线程之外,node.js 还会产生四个线程,但它们都没有用于网络 I/O,例如数据库操作。线程是:
DNS 解析器(因为大多数操作系统仅为此提供同步 API)
文件系统 API(因为异步跨平台这样做很麻烦)
加密(因为这使用 CPU)
Zlib(zip 压缩)
除非您自己生成,否则其他所有内容都不要使用线程worker_threads。有关更多信息,请参阅节点自己的文档:https : //nodejs.org/en/docs/guides/dont-block-the-event-loop/。不要依赖不是来自 node.js 项目本身的信息,例如 youtube 或媒体文章,这些文章说节点 I/O 使用线程池 - 他们不知道他们在说什么。
增加线程池大小不会对网络 I/O 做任何事情,因为 node.js 根本没有任何代码来使网络 I/O 利用额外的线程。如果您想将负载分散到多个处理器上,您可以使用集群。您可以编写自己的集群代码或使用pm2等进程管理器的集群模式将连接传递给您的进程。
大多数非系统程序员没有意识到的是,等待 I/O 的 CPU 时间恰好为零。通过生成线程来实现这意味着您要分配大量的 RAM,并且大多数情况下所有这些线程都使用零CPU 时间(想象一下生成 1024 个线程,每个线程根本不使用 CPU)。当这些线程(或者在 node.js 的情况下是主线程)正在等待来自数据库的 1000 个回复时,操作系统将这些请求排入一系列数据包并将它们发送到您的网卡,后者又将它们发送到数据库一次一点- 是的,其核心的 I/O 不是并行的(除非您在多个网卡上使用中继)。所以大部分繁重的工作都是通过以太网完成的,而您的进程被操作系统暂停(等待)。
node.js 所做的是,当请求正在等待时,它会发出另一个请求。这就是非阻塞的意思。在处理所有其他请求之前,节点不会等待请求完成。这意味着默认情况下,您在 node.js 中发出的所有请求都是并发的——它们不会等待其他请求完成。
在请求完成端,从服务器收到的任何响应都会触发节点搜索事件队列(实际上这只是一个集合,因为队列中的任何项目都可以随时完成)并找到相应的回调来调用。执行回调确实需要 CPU 时间,但不会等待网络请求。
这就是像 node.js 这样的系统可以与多线程系统竞争的原因。事实上,在某些情况下可以胜过多线程系统,因为在同一个线程上执行它意味着您不需要锁(互斥锁或信号量)并且您避免了上下文切换的成本(当操作系统将一个线程置于睡眠状态时,复制所有线程)寄存器值到 RAM,然后唤醒另一个线程,从 RAM 中为新进程复制寄存器值)。
| 归档时间: |
|
| 查看次数: |
3309 次 |
| 最近记录: |