Ich habe versehentlich einen Artikel darüber gesehen, dass das Senden von HTTP-Anfragen unter NodeJS keine DNS-Ergebnisse zwischenspeichert. Dies bedeutet, dass, wenn Sie ein HTTP-Erfassungsprogramm basierend auf NodeJS schreiben und kein DNS-Caching bereitstellen, jede Anfrage den Domänennamen törichterweise wiederholt in eine IP-Adresse auflöst. Klingt so, als würde es die Leistung stark beeinträchtigen, oder?
In meinem Projekt wird beim Senden von HTTP-Anfragen nicht die native HTTP-Bibliothek des Knotens verwendet, sondern eine häufig verwendete Request-Bibliothek. Ich habe die relevanten Dokumente und Github-Probleme der Bibliothek überprüft und auch einige Beiträge zum Thema DNS gefunden. Die meisten Leute sagen jedoch, dass das DNS-Problem selbst nicht im Bereich der Request-Bibliothek liegt, sondern dem Kernproblem von NodeJS zugeschrieben wird. Oh mein Gott, es fühlt sich so tiefgründig an!
Glücklicherweise wurden im oben genannten Artikel auch zwei Lösungen vorgeschlagen:
Anwendungsebene: dnscache
Betriebssystemebene: Bind, dnsmasq und unbound
Egal welche Die von Ihnen gewählte Lösung scheint sehr einfach zu sein: Installieren und initialisieren Sie sie einfach. Die Frage ist jedoch: Wie überprüfen wir, ob sie real und wirksam sind? Da die Betriebssystemumgebung meiner lokalen Entwicklungsmaschine Win7 64bit ist, kann ich die oben erwähnte Lösung auf Betriebssystemebene nicht testen. Schauen wir uns dann an, ob die Lösung auf Anwendungsebene effektiv ist ~~
Zuerst müssen wir Win aktivieren, um DNS-Anfragen zu verfolgen. Hier habe ich eine Software gefunden, die nach dem Herunterladen direkt ausgeführt werden kann. Dann brauchen wir auch eine Methode, um den Cache zu leeren. Um es einfach auszudrücken:
ipconfig /flushdns
Die Das Tool ist fertig. Erstellen wir ein Testskript:
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); });
Okay, jetzt öffnen Sie DNSQuerySniffer, bereinigen Sie dann zuerst den lokalen DNS-Cache und führen Sie unseren Test aus Skript, wenn alles fertig ist nodetest.js. Sie sehen eine DNS-Anfrage und die zugehörigen Informationen in DNSQuerySniffer. Wenn Sie unser Testskript innerhalb eines bestimmten Zeitintervalls wiederholt ausführen, werden Sie feststellen, dass die DNS-Anfrage nicht erneut ausgelöst wird. Was bedeutet das? Meine Win7-Umgebung selbst verfügt über einen DNS-Cache auf Betriebssystemebene (die Cache-Zeit ist jedoch sehr kurz).
Ändern Sie unser Testskript wie folgt:
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); });
Dieses Mal leeren wir schnell den lokalen DNS-Cache nach der Ausführung des Testskripts (wenn Sie nicht schnell sind, Sie Wenn Sie das Triggerintervall von setTimeout ordnungsgemäß verlängern, werden Sie feststellen, dass die HTTP-Anfrage nach zwei Sekunden keine erneute DNS-Abfrage durchführt. Offensichtlich verwaltet unsere Anwendung ihren eigenen DNS-Cache, sodass es der zweiten Anfrage egal ist, ob der entsprechende DNS-Cache-Eintrag lokal im Betriebssystem vorhanden ist.