DNS 結果をキャッシュせずに、nodejs で http リクエストを送信することに関する記事を偶然見ました。これは、nodejs に基づいて http 収集プログラムを作成する場合、DNS キャッシュを提供しないと、各リクエストが愚かにもドメイン名を IP アドレスに繰り返し解決することを意味します。それはパフォーマンスに大きな影響を与えるように思えますよね?
私のプロジェクトでは、http リクエストの送信にはノードのネイティブ http ライブラリを使用せず、一般的に使用されるリクエスト ライブラリに依存します。ライブラリの関連ドキュメントや github の問題を確認したところ、DNS に関連する投稿もいくつか見つかりました。しかし、ほとんどの人が言っているのは、DNS の問題自体は Request ライブラリの範囲内ではなく、nodejs の中核的な問題に起因しているということです。うーん、とても奥深い感じがします!
幸いなことに、上記の記事では 2 つの解決策も提案されています:
アプリケーション レベル: dnscache
OS レベル: Bind、dnsmasq、および unbound
どの解決策であっても、インストールして初期化するだけで非常に簡単のようです。それ。しかし問題は、それらが本物で効果的であることをどのように検証するかということです。私のローカル開発マシンのオペレーティング システム環境は win7 64 ビットであるため、上記のオペレーティング システム レベルのソリューションをテストできません。次に、アプリケーションレベルのソリューションが効果的かどうかを見てみましょう~~
まず、DNSリクエストを追跡するためにWinを有効にする必要があります。ここで、ダウンロード後にインストールせずに直接実行できるソフトウェアを見つけました。次に、キャッシュをクリアするメソッドも必要です。ここで確認できます。ターミナルで実行するだけです:
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); });
わかりましたはい、DNSQuerySniffer を開き、すべての準備ができたら、まずローカル DNS キャッシュをクリーンアップします。テスト スクリプト ノード 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 のトリガー間隔を適切に延長できます)。 2 秒後続の http リクエストでは DNS が再クエリされません。これはどういう意味ですか?明らかに、アプリケーションは独自の DNS キャッシュを維持するため、2 番目のリクエストでは、対応する DNS キャッシュ レコードがオペレーティング システムにローカルに存在するかどうかは関係ありません。