Node.js dns.resolve() 与 dns.lookup() [英] Node.js dns.resolve() vs dns.lookup()

查看:25
本文介绍了Node.js dns.resolve() 与 dns.lookup()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在 Node.js 中查找给定主机的相应 IP.似乎有两种本地方法可以做到这一点:

>dns.resolve('google.com', (error,addresses) => { console.error(error); console.log(addresses); });QueryReqWrap {绑定名称:'查询A',回调:{[功能:asyncCallback]立即:真},主机名:'google.com',oncomplete: [功能: onresolve],领域:领域 {域:空,_events: { 错误: [功能] },_eventsCount: 1,_maxListeners:未定义,成员:[] } }>空值['216.58.194.174']

还有:

>dns.lookup('google.com', (error, address, family) => { console.error(error); console.log(address); console.log(family); });GetAddrInfoReqWrap {回调:{[功能:asyncCallback]立即:真},家庭:0,主机名:'google.com',oncomplete:[功能:onlookup],领域:领域 {域:空,_events: { 错误: [功能] },_eventsCount: 1,_maxListeners:未定义,成员:[] } }>空值216.58.194.1744

两者都返回相同的 IPv4 地址.dns.lookup()dns.resolve() 有什么区别?另外,对于每秒大量请求,哪个性能更好?

解决方案

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() 函数的行为,但请注意,更改这些文件将更改运行在同一操作系统上的所有其他程序的行为.

尽管对 dns.lookup() 的调用从 JavaScript 的角度来看是异步的,但它是作为对运行在 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() 请求 do 因为它们调用通常阻塞的 OS DNS 解析器(尽管现在有某种异步接口——但它们不一定在所有地方都实现).

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

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?

解决方案

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

这篇关于Node.js dns.resolve() 与 dns.lookup()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆