【问题标题】:why libuv do DNS request by multiple thread为什么libuv通过多线程做DNS请求
【发布时间】:2017-06-17 09:41:43
【问题描述】:

有时我的服务总是发送很大差异的主机名url,我会重新构建我的docker容器,同时容器重新启动,一些http请求会失败:

events.js:154
  throw er; // Unhandled 'error' event
  ^
Error: getaddrinfo ENOTFOUND www.videojj.com www.videojj.com:80
at errnoException (dns.js:26:10)
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:77:26)

我不确定原因,我知道DNS,libuv中的多线程文件操作。我很困惑为什么DNS请求不能在libuv中使用IO复用机制

【问题讨论】:

    标签: node.js dns libuv


    【解决方案1】:

    正如你所提到的,根据documentation(强调我的):

    libuv 提供了一个线程池,可用于运行用户代码并在循环线程中获得通知。 此线程池在内部用于运行所有文件系统操作,以及 getaddrinfo 和 getnameinfo 请求

    uvbook 给出了一些其他提示:

    线程在内部用于伪装所有系统调用的异步特性。 libuv 还使用线程允许您(应用程序)异步执行实际上是阻塞的任务,方法是生成一个线程并在完成时收集结果。

    那么,回到你的问题:

    为什么DNS请求不能在libuv中使用IO复用机制

    这是因为 fs 操作和(让我说)DNS 请求 阻塞了系统调用。因此,如果在主线程上执行,它们将破坏 libuv 的异步特性并强制循环停止。没有办法,只能在单独的线程上启动它们以保持循环正常运行,直到工作完成。

    请注意,getaddrinfogetnameinfo 也存在非阻塞版本,但它们不可移植,因此 libuv 不能一直使用它们。
    有关详细信息,请参阅 SO 上的this question

    【讨论】:

    • 谢谢你的回复,我只是想知道为什么DNS请求是一个阻塞操作。
    • @bugall 你确实问了一些不同的问题。无论如何,它们在设计上是同步的,并且它们具有异步对应物(不幸的是不可移植)。 Libuv 只能将它们放在线程上。就是这样。
    • @bugall:DNS 的 API 是阻塞的,至少在 POSIX 中是这样。 (libuv 试图与 POSIX 保持一致;在 DNS 的情况下,您可能甚至无法通过线程/进程以外的其他简单方式获得异步性。)
    【解决方案2】:

    也许,我们在发送请求之前需要知道主机IP地址,因此,发送请求和DNS请求都必须同步,因为libuv中的IO-Multiplexing工作在主线程上,把主线程同步操作,所以DNS请求使用线程池。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-25
      • 2016-02-16
      • 2010-11-15
      • 1970-01-01
      • 2012-06-08
      • 1970-01-01
      • 1970-01-01
      • 2023-02-16
      相关资源
      最近更新 更多