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

Jus*_*tin 10 javascript dns ipv4 ipv6 node.js

我需要在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' ]
Run Code Online (Sandbox Code Playgroud)

和:

> 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
Run Code Online (Sandbox Code Playgroud)

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

msc*_*dex 18

dns文档已经介绍了区别:

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

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

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

dns.resolve(),dns.resolve*()和dns.reverse()
这些函数的实现方式与dns.lookup()完全不同.他们不使用getaddrinfo(3),他们总是在网络上执行DNS查询.此网络通信始终是异步完成的,并且不使用libuv的线程池.

因此,这些函数不会对dns.lookup()可以在libuv的线程池上发生的其他处理产生相同的负面影响.

它们不使用与dns.lookup()使用相同的配置文件集.例如,他们不使用/ etc/hosts中的配置.

并发性而言,最好使用,dns.resolve*()因为这些请求不会在线程池中结束,而dns.lookup()请求因为它们调用OS DNS解析器(通常会阻塞)(尽管现在有某种异步接口 - - 但它们并不一定在所有地方实施).

目前,节点内部dns.lookup()用于任何自动DNS解析,例如将主机名传递给http.request().