首頁  >  文章  >  web前端  >  Nodejs下DNS快取問題淺析

Nodejs下DNS快取問題淺析

高洛峰
高洛峰原創
2016-12-06 15:44:461824瀏覽

無意間看到一個文章,是關於nodejs下發送http請求不會快取dns結果的。這意味著,如果你基於nodejs寫了一個http採集程序,不提供dns快取則會讓每次請求都傻傻的重複解析網域為ip位址。聽起來會非常影響性能不是麼?

我的專案中,發送http請求並不是使用的node原生的http函式庫,而是依賴一個常用的Request函式庫。我查閱了一下該函式庫的相關文件和github issue,也發現了一些和dns相關的貼文。不過多數說的是,關於dns問題,本身並不是Request函式庫的範疇,而是歸結於nodejs的核心問題。 omg,感覺好深奧!

幸好,上面提到的那篇文章中也提出了兩個解決方案:

應用程式等級:dnscache

作業系統層級:Bind, dnsmasq 和unbound

不論是哪個方案,看起來似乎都很簡單,只是安裝並初始化即可。但問題是,我們要怎麼驗證它們真實有效?由於我本地的開發機作業系統環境是win7 64bit,所以上文提到的作業系統層級的方案我無法測試。那我們就來看看應用程式等級方案到底是否有效吧~~

首先,我們需要讓win能追蹤dns請求,這裡我找到了一個軟體,下載後不需要安裝直接運作即可。然後,我們還需要一個清除快取的方法,可以看這裡,簡單說就是在終端中執行:

ipconfig /flushdns

   

工具就準備完畢了,我們創建一個測試腳本:

const Request = require('request');
function fetch(url, callback){
Request.head({
url: url,
timeout: 10000,
tunnel: true,
gzip: true,
proxy: false,
followRedirect: false
}, callback);
}
let now = Date.now();
fetch('http://blog.kazaff.me', function(err, response, body){
console.log('lookup time without cache: ', Date.now() - now);
});

工具就準備完畢了,我們創建一個測試腳本:

rr的,現在打開DNSQuerySniffer,然後先清理一下本地DNS緩存,一切就緒後執行我們的測試腳本node test.js。你會在DNSQuerySniffer中看到一次DNS請求及其相關資訊。在一定的時間間隔內,反覆執行我們的測試腳本你會發現並不會再次觸發DNS請求,這說明什麼?我的win7環境本身就自備作業系統層級的DNS快取(只是快取時間很短)。

修改我們的測試腳本如下:

const dnscache = require('dnscache')({
"enable": true
});
const Request = require('request');
function fetch(url, callback){
Request.head({
url: url,
timeout: 10000,
tunnel: true,
gzip: true,
proxy: false,
followRedirect: false
}, callback);
}
let now = Date.now();
fetch('http://priceline.com', function(err, response, body){
console.log('lookup time without cache: ', Date.now() - now);
setTimeout(function(){
now = Date.now();
fetch('http://priceline.com', function(err, response, body){
console.log('lookup time with cache: ', Date.now() - now);
});
}, 2000);
});

這次我們在執行測試腳本後,快速清空本地DNS快取(如果你手速不快,可以適當延長setTimeout的觸發間隔),你會發現,兩秒後的http請求並沒有重新查詢DNS,這說明什麼?很明顯,我們的應用程式自己維護了DNS緩存,所以第二次請求根本不會關心作業系統本地是否有對應的DNS快取記錄。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn