Node.js dns.resolve()与dns.lookup()

我需要在Node.js中查找给定的主机到其对应的IP。 似乎有两个原生的方法来做到这一点:

> dns.resolve('google.com', (error, addresses) => { console.error(error); console.log(addresses); }); QueryReqWrap { bindingName: 'queryA', callback: { [Function: asyncCallback] immediately: true }, hostname: 'google.com', oncomplete: [Function: onresolve], domain: Domain { domain: null, _events: { error: [Function] }, _eventsCount: 1, _maxListeners: undefined, members: [] } } > null [ '216.58.194.174' ] 

和:

 > dns.lookup('google.com', (error, address, family) => { console.error(error); console.log(address); console.log(family); }); GetAddrInfoReqWrap { callback: { [Function: asyncCallback] immediately: true }, family: 0, hostname: 'google.com', oncomplete: [Function: onlookup], domain: Domain { domain: null, _events: { error: [Function] }, _eventsCount: 1, _maxListeners: undefined, members: [] } } > null 216.58.194.174 4 

两者都返回相同的IPv4地址。 dns.lookup()dns.resolve()什么区别? 而且,每秒钟处理大量请求的性能更高?

dns文档已经描述了这个区别:

尽pipedns.lookup()和各种dns.resolve *()/ dns.reverse()函数具有将networking名称与networking地址关联的相同目标(反之亦然),但它们的行为却完全不同。 这些差异会对Node.js程序的行为产生微妙而重大的影响。

dns.lookup()
在引擎盖下,dns.lookup()使用与大多数其他程序相同的操作系统设施。 例如,dns.lookup()几乎总是以与ping命令相同的方式parsing给定名称。 在大多数类似POSIX的操作系统中,可以通过更改nsswitch.conf(5)和/或resolv.conf(5)中的设置来修改dns.lookup()函数的行为,但请注意,更改这些文件将更改在同一操作系统上运行的所有其他程序的行为。

尽pipe对dns.lookup()的调用将从JavaScript的angular度来看是asynchronous的,但是它被实现为在libuv的线程池上运行的getaddrinfo(3)的同步调用。 由于libuv的线程池的大小是固定的,这意味着如果由于某种原因调用getaddrinfo(3)需要很长时间,那么其他可能在libuv线程池上运行的操作(例如文件系统操作)将会经历性能下降。 为了缓解这个问题,一个可能的解决scheme是通过将'UV_THREADPOOL_SIZE'环境variables设置为大于4(当前默认值)的值来增加libuv线程池的大小。 有关libuv线程池的更多信息,请参阅官方的libuv文档。

dns.resolve(),dns.resolve *()和dns.reverse()
这些函数的实现与dns.lookup()完全不同。 他们不使用getaddrinfo(3),他们总是在networking上执行DNS查询。 这个networking通信总是asynchronous完成的,不使用libuv的线程池。

因此,这些函数对dns.lookup()可能具有的libuv线程池上发生的其他处理没有同样的负面影响。

他们不使用与dns.lookup()使用的configuration文件相同的configuration文件。 例如,他们不使用/ etc / hosts中的configuration。

并发性而言,最好使用dns.resolve*()因为这些请求不会在线程池中结束,而执行dns.lookup()请求因为它们调用通常阻塞的操作系统DNSparsing器虽然现在有一些asynchronous接口,但是它们不一定能在任何地方实现)。

目前,节点内部使用dns.lookup()进行任何自动DNSparsing,例如将主机名传递给http.request()