Verzögerungen bei HTTP-Anfragen über Node.js im Vergleich zum Browser

8

Bei der Verwendung von Node.js zum Abfragen einiger öffentlicher APIs über HTTP-Anforderungen. Daher verwende ich das request -Modul. Ich messe die Antwortzeit innerhalb meiner Anwendung und stelle fest, dass meine Anwendung die Ergebnisse von API-Abfragen etwa 2-3 Mal langsamer als "direkte" Anfragen per Curl oder im Browser zurückgibt. Außerdem habe ich bemerkt, dass Verbindungen zu HTTPS-fähigen Diensten normalerweise länger dauern als einfache HTTP-Dienste, aber dies kann ein Zufall sein.

Ich habe versucht, meine Optionen request zu optimieren, aber ohne Erfolg. Zum Beispiel frage ich

ab

Ссылка

Ich verwende request.defaults , um die allgemeinen Standardwerte für alle Anfragen festzulegen:

%Vor%

Die eigentliche Anfrage erfolgt über

%Vor%

Sieht jemand Optimierungspotential? Mache ich etwas völlig falsches? Vielen Dank im Voraus für einen Rat!

    
Tobi 06.03.2015, 08:14
quelle

2 Antworten

4

Es gibt mehrere mögliche Probleme, die Sie angehen müssen, wenn ich das verstehe, was ich von Ihrer Architektur verstehe. In keiner bestimmten Reihenfolge sind sie:

  • Die Verwendung von request ist immer langsamer als die Verwendung von http direkt, da der weise Mann einmal sagte: "Abstraktionskosten". ;) Um alle möglichen Unze der Leistung herauszufordern, würde ich alle HTTP-Anfragen mit dem net -Modul des Knotens direkt bearbeiten. Für HTTPS lohnt es sich nicht, das https -Modul neu zu schreiben. Und für die Aufzeichnung ist HTTPS per Definition immer langsamer als HTTP, da sowohl kryptografische Schlüssel als auch kryptografische Schlüssel verschlüsselt werden müssen und die Crypt / Decrypt-Arbeit an der Payload durchgeführt wird.
  • Wenn Ihre Anforderungen das Abrufen mehrerer Ressourcen von einem einzelnen Server umfassen, stellen Sie sicher, dass diese Anforderungen der Reihe nach mit dem KeepAlive-Set von HTTP ausgeführt werden, damit Sie von dem bereits geöffneten Socket profitieren können. Die Zeit, die für das Handshake eines neuen TCP-Sockets benötigt wird, ist sehr groß im Vergleich zu einer Anfrage für einen bereits geöffneten Socket.
  • stellen Sie sicher, dass das HTTP-Verbindungs-Pooling deaktiviert ist (siehe Nodejs Max Socket Pooling-Einstellungen )
  • stellen Sie sicher, dass Ihr Betriebssystem und Ihre Shell die Anzahl der verfügbaren Sockets nicht einschränkt. Siehe Wie viele Socket-Verbindungen möglich? für Hinweise.
  • Wenn Sie Linux verwenden, überprüfen Sie Zunehmend die maximale Anzahl von TCP / IP-Verbindungen in Linux und ich würde auch dringend empfehlen, die Kernel-Socket-Puffer zu optimieren.

Ich werde weitere Vorschläge hinzufügen, wenn sie mir einfallen.

Aktualisieren

Mehr zum Thema Mehrfachanforderungen an denselben Endpunkt:

Wenn Sie mehrere Ressourcen von demselben Endpunkt abrufen müssen, ist es sinnvoll, Ihre Anforderungen an bestimmte Worker zu segmentieren, die offene Verbindungen zu diesem Endpunkt aufrechterhalten. Auf diese Weise können Sie sicher sein, dass Sie die angeforderte Ressource so schnell wie möglich ohne den Overhead des anfänglichen TCP-Handshakes erhalten können.

TCP-Handshake ist ein dreistufiger Prozess.

Schritt eins: Client sendet ein SYN-Paket an den Remote-Server. Schritt zwei: Der Remote-Server antwortet dem Client mit einem SYN + ACK. Schritt drei: Der Client antwortet dem Remote-Server mit einem ACK.

Abhängig von der Latenz des Clients zum Remote-Server kann sich dies (wie William Proxmire einmal sagte) "echtes Geld" oder in diesem Fall Verzögerung ergeben.

Von meinem Desktop aus beträgt die aktuelle Latenz (Umlaufzeit durch Ping) für ein 2K Oktett-Paket nach www.google.com zwischen 37 und 227 ms.

Unter der Annahme, dass wir uns auf einen Round-Trip-Durchschnitt von 95ms (über eine perfekte Verbindung) verlassen können, würde die Zeit für den ersten TCP-Handshake bei 130ms oder SYN (45ms) + SYN + ACK (45ms) + ACK liegen. 45ms) und das ist ein Zehntel einer Sekunde, nur um die erste Verbindung herzustellen.

Wenn die Verbindung erneut übertragen werden muss, könnte sie viel dauern.

Dies setzt voraus, dass Sie eine einzelne Ressource über eine neue TCP-Verbindung abrufen.

Um dies zu verbessern, sollten Ihre Mitarbeiter einen Pool offener Verbindungen zu "bekannten" Zielen haben, die sie dann dem Supervisor-Prozess ankündigen würden, damit sie Anfragen an den am wenigsten belasteten Server mit einer "Live" -Verbindung leiten könnten auf den Zielserver.

    
Rob Raisch 16.04.2015, 19:26
quelle
3

Tatsächlich habe ich einige neue Elemente, die gut genug sind, um eine echte Antwort zu geben. Wenn Sie sich die Art und Weise ansehen, wie request den HTTP-Agenten verwendet , versuchen Sie es bitte Folgendes:

%Vor%

Dies wird das Verbindungspooling deaktivieren und sollte es viel schneller machen.

    
Tristan Foureur 15.04.2015 15:10
quelle

Tags und Links