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

问题描述 投票:10回答:2

我需要在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()有什么区别?而且,每秒大量请求的性能更高?

javascript node.js dns ipv6 ipv4
2个回答
16
投票

dns documentation已经描述了差异:

Although dns.lookup() and the various dns.resolve*()/dns.reverse() functions have the same goal of associating a network name with a network address (or vice versa), their behavior is quite different. These differences can have subtle but significant consequences on the behavior of Node.js programs.

dns.lookup()
Under the hood, dns.lookup() uses the same operating system facilities as most other programs. For instance, dns.lookup() will almost always resolve a given name the same way as the ping command. On most POSIX-like operating systems, the behavior of the dns.lookup() function can be modified by changing settings in nsswitch.conf(5) and/or resolv.conf(5), but note that changing these files will change the behavior of all other programs running on the same operating system.

Though the call to dns.lookup() will be asynchronous from JavaScript's perspective, it is implemented as a synchronous call to getaddrinfo(3) that runs on libuv's threadpool. Because libuv's threadpool has a fixed size, it means that if for whatever reason the call to getaddrinfo(3) takes a long time, other operations that could run on libuv's threadpool (such as filesystem operations) will experience degraded performance. In order to mitigate this issue, one potential solution is to increase the size of libuv's threadpool by setting the 'UV_THREADPOOL_SIZE' environment variable to a value greater than 4 (its current default value). For more information on libuv's threadpool, see the official libuv documentation.

dns.resolve(), dns.resolve*() and dns.reverse()
These functions are implemented quite differently than dns.lookup(). They do not use getaddrinfo(3) and they always perform a DNS query on the network. This network communication is always done asynchronously, and does not use libuv's threadpool.

As a result, these functions cannot have the same negative impact on other processing that happens on libuv's threadpool that dns.lookup() can have.

They do not use the same set of configuration files than what dns.lookup() uses. For instance, they do not use the configuration from /etc/hosts.

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

目前,node在内部使用dns.lookup()进行任何自动DNS解析,例如将主机名传递给http.request()时。


0
投票

@mscdex的回答非常充实并且在解释。我可以添加一个关于我们用来绕过线程阻塞的方法的信息。

我们开发了一个替换/扩展节点的dns.lookup方法的模块。模块缓存响应,具有多记录解析和TTL支持。此外,我们有良好的单位和功能tests with 100% coverage。模块在生产和高负载环境中进行了测试。在MIT许可下。这是:https://github.com/LCMApps/dns-lookup-cache

如果您需要查找方法的支持但不起作用,如阻止应用程序或响应减慢等负面影响,您可以使用我们的模块。我相信它会有所帮助!

© www.soinside.com 2019 - 2024. All rights reserved.