【问题标题】:What happens if all node.js's worker threads are busy如果所有 node.js 工作线程都忙,会发生什么
【发布时间】:2015-06-15 11:53:39
【问题描述】:

我试图了解 node.js 是如何工作的,尽管我已经阅读了这篇文章:When is the thread pool used? 我不确定如果所有工作线程都忙并且准备好执行另一个异步 I/O 操作会发生什么。

如果我的这篇http://www.future-processing.pl/blog/on-problems-with-threads-in-node-js/ 文章正确,事件循环将被阻塞,直到有工作线程空闲来处理额外的 I/O 操作。这意味着如果五个用户试图同时访问一个网页(比如他们的个人资料页面,可以说需要一个 db-query),第 5 个用户将被阻止,直到第一个 db-query 完成并且这个工作线程再次空闲?

【问题讨论】:

  • 请记住,您必须检查您的数据库库是如何进行 I/O 的。它可能使用也可能不使用 nodejs 线程池。
  • 如果您发布更多关于您正在做什么和您的想法的完整示例,这将对我有所帮助。例如,您正在运行什么类型的网络服务器?简而言之,您的多线程应用程序的架构是什么?在什么环境中使用它?
  • 我没有什么特别的想法;我只是好奇而已。我知道贝宝正在使用节点,并且我认为每个数据库查询都将在工作线程中执行,以免使主事件循环变黑。

标签: javascript node.js multithreading


【解决方案1】:

I/O 通常不会阻塞 事件循环(目前有一些例外,例如 crypto 模块和 fs.*Sync() 方法之类的东西),尤其是在网络 I/ 的情况下O,libuv线程池根本不用(仅用于dns(当前)和fs操作之类的东西)。

如果您的数据库驱动程序是用 C++ 作为 node.js 插件编写的,那么它可能会阻塞事件循环(它正在做同步的事情)或者它可能正在使用 libuv 线程池。但是,如果数据库驱动程序只用 JavaScript 编写,它通常会使用某种网络 I/O,如前所述,它不会阻塞任何东西,也不会使用 libuv 线程池。

因此,在您的示例中,根据数据库驱动程序的实现方式,可以同时为所有 5 个用户提供服务。例如,协议级别的 MySQL 每个连接一次只支持一个未完成的查询。因此,大多数用于 node.js 的 MySQL 驱动程序所做的是将其他查询排队,直到当前查询完成。但是,MySQL 驱动程序完全有可能在内部维护某种连接池,以便您拥有更高的并发性。

但是,如果 5 个请求中的每一个都导致某些内容来自磁盘,那么第 5 个请求可能必须等到其他 4 个 fs 请求之一完成,因为当前的默认大小libuv 线程池。这并不意味着事件循环本身被阻塞,因为它仍然可以为新的传入请求和其他东西提供服务,但第 5 个客户端只需要等待更长的时间。

【讨论】:

  • 感谢您的回答。我最初的问题应该更准确,但是您几乎回答了我不确定的所有问题。我的意思是异步操作(例如通过 mongoose 进行的 mongoDB 查询)。那么在工作线程中执行的操作是否有任何类型的队列?
  • 基于一些快速的谷歌搜索,似乎 mongodb 有一个类似的限制——每个连接一个未完成的查询。但是mongoose 模块内部支持连接池 (poolSize)。任何发往 libuv 线程池的操作都有一个队列。正如我在回答中提到的,这包括 DNS 查询(当前)和文件系统操作。
【解决方案2】:

是否有任何类型的队列用于在工作线程中执行的操作?

是的。 libuv 管理这个队列。所有工作线程都可能被占用,在这种情况下,进入工作池的新异步请求将无法进行。请注意,“异步 FS 请求”仍必须在某处完成,并且会阻塞正在处理它的工作线程,直到完成为止。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-10
    • 1970-01-01
    • 2012-08-06
    相关资源
    最近更新 更多