2016-12-05 42 views
5

我需要给定主机查找到Node.js的相应的IP似乎有这样两种本地方法:的Node.js dns.resolve()VS dns.lookup()

> 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()有何区别?另外,哪个更适合每秒处理大量请求?

回答

6

dns documentation已经介绍了区别:

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

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

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

dns.resolve(),dns.resolve *()和dns.reverse()
这些功能被实现相当不同于dns.lookup()。他们不使用getaddrinfo(3),他们总是在网络上执行DNS查询。这种网络通信总是异步完成的,并且不使用libuv的线程池。

其结果是,这些功能不能有,关于libuv的发生线程池该dns.lookup(其它处理)相同的负面影响可以有。

他们不使用同一套配置文件比dns.lookup()使用。例如,他们不使用/ etc/hosts中的配置。

至于并发的话,你是使用dns.resolve*()更好,因为这些请求不会在线程池结束,而dns.lookup()请求因为他们叫出通常块操作系统的DNS解析器(尽管现在有一些异步接口 - 但它们并不一定在任何地方实现)。

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

+0

值得一提的是,每次解析的IP地址列表都以不同的顺序出现。这可以用于负载平衡(使用循环方法进行DNS解析)。 https://www.nginx.com/resources/glossary/dns-load-balancing/ – rocketspacer