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

ⅰ亾dé卋堺 提交于 2019-12-18 07:37:25

问题


I need to lookup a given host to its corresponding IP in Node.js. There seems to be two native methods of doing this:

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

And:

> 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

Both return the same IPv4 address. What is the difference between dns.lookup() and dns.resolve()? Also, which is more performant for lots of requests per second?


回答1:


The dns documentation already describes the difference:

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.

As far as concurrency goes, you are better off using dns.resolve*() because those requests do not end up in the thread pool, whereas dns.lookup() requests do because they call out to the OS DNS resolver which typically blocks (although there are some kind of-async interfaces now -- but they are not necessarily implemented everywhere).

Currently, node internally uses dns.lookup() for any automatic DNS resolution, like when you pass a hostname to http.request().




回答2:


@mscdex answer is really full and explaining. I may add an info about approach we use to bypass thread blocking.

We developed a module that replaces/extends node's dns.lookup method. Module caches responses, has multi-records resolving and TTL support. Also we have good unit and functional tests with 100% coverage. Module was tested in production and highload environments. Under MIT license. Here it is: https://github.com/LCMApps/dns-lookup-cache

If you need support of lookup method but don't work negative effects like blocking of application or responses slow downs you may use our module. I believe it will help!



来源:https://stackoverflow.com/questions/40985367/node-js-dns-resolve-vs-dns-lookup

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!