2016-12-05 96 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