一尘不染

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

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' ]

和:

> 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()?另外,每秒处理大量请求中哪个性能更高?


阅读 504

收藏
2020-07-07

共1个答案

一尘不染

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()

2020-07-07