为什么libuv通过多个线程进行DNS请求

时间:2017-06-17 09:41:44

标签: node.js dns libuv

有时我的服务会一直发送大的diffirence hostname 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多路复用机制

2 个答案:

答案 0 :(得分:1)

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

  

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

uvbook提供了一些其他提示:

  

内部使用线程来伪造所有系统调用的异步性质。 libuv还使用线程允许您(应用程序)通过生成线程并在结束时收集结果来异步执行实际阻塞的任务。

所以,回到你的问题:

  

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

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

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

答案 1 :(得分:0)

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