it-swarm.com.de

HTTP2 mit node.js hinter dem Nginx-Proxy

Ich habe einen node.js-Server, der hinter einem Nginx-Proxy ausgeführt wird. Auf node.js wird auf Port 3000 ein HTTP 1.1-Server (kein SSL) ausgeführt. Beide Server werden auf demselben Server ausgeführt.

Ich habe kürzlich Nginx für die Verwendung von HTTP2 mit SSL (h2) eingerichtet. Es scheint, dass HTTP2 in der Tat aktiviert ist und funktioniert.

Ich möchte jedoch wissen, ob sich die Tatsache, dass die Proxy-Verbindung (nginx <-> node.js) HTTP 1.1 verwendet, auf die Leistung auswirkt. Das heißt, vermisse ich die Vorteile von HTTP2 in Bezug auf die Geschwindigkeit, weil meine interne Verbindung HTTP 1.1 ist?

33
Shade

Im Allgemeinen ist der größte unmittelbare Vorteil von HTTP/2 die Geschwindigkeitssteigerung durch Multiplexing für die Browserverbindungen, die häufig durch eine hohe Latenz (d. H. Langsame Umlaufgeschwindigkeit) behindert werden. Dies reduziert auch die Notwendigkeit (und die Kosten) mehrerer Verbindungen, um ähnliche Leistungsvorteile in HTTP/1.1 zu erzielen.

Für interne Verbindungen (z. B. zwischen einem Webserver, der als Reverse-Proxy fungiert, und Back-End-App-Servern) ist die Latenz normalerweise sehr, sehr gering, sodass die Geschwindigkeitsvorteile von HTTP/2 vernachlässigbar sind. Außerdem wird jeder App-Server in der Regel bereits eine separate Verbindung sein, sodass hier wiederum keine Gewinne erzielt werden.

Sie erhalten also die meisten Ihres Leistungsvorteils, wenn Sie nur HTTP/2 am Rande unterstützen. Dies ist eine ziemlich häufige Einrichtung - ähnlich wie HTTPS häufig auf dem Reverse-Proxy/Load-Balancer beendet wird, anstatt vollständig durchzugehen.

Die vollständige Unterstützung von HTTP/2 bietet jedoch potenzielle Vorteile. Beispielsweise könnte es Server-Push von der Anwendung aus zulassen. Potenzielle Vorteile ergeben sich auch aus der geringeren Paketgröße für diesen letzten Hop aufgrund der binären Natur von HTTP/2 und der Header-Komprimierung. Wie bei der Latenz ist auch bei internen Verbindungen die Bandbreite in der Regel ein geringeres Problem, weshalb die Bedeutung dieser Tatsache fraglich ist. Schließlich argumentieren einige, dass ein Reverse-Proxy beim Verbinden einer HTTP/2-Verbindung mit einer HTTP/2-Verbindung weniger funktioniert als bei einer HTTP/1.1-Verbindung, da kein Protokoll in das andere konvertiert werden muss, obwohl ich skeptisch bin, ob das überhaupt ist Dies fällt auf, da es sich um separate Verbindungen handelt (es sei denn, es handelt sich lediglich um eine TCP pass through proxy). Aus meiner Sicht besteht der Hauptgrund für End-to-End-HTTP/2 darin, End-to-End-Server zuzulassen Push, aber auch das wird wahrscheinlich besser mit HTTP-Link-Headern und 103-Early-Hints behandelt, da die Verwaltung von Push über mehrere Verbindungen kompliziert ist .

Im Moment würde ich nur empfehlen, HTTP/2 am Endpunkt zu verwenden, während die Server weiterhin Unterstützung hinzufügen und die Server-Push-Nutzung gering ist (und noch experimentiert wird, um die besten Vorgehensweisen zu definieren). Nginx unterstützt zum Zeitpunkt des Schreibens auch kein HTTP/2 für ProxyPass-Verbindungen (obwohl Apache dies tut) und hat keine Pläne, dies hinzuzufügen , und sie machen einen interessanten Punkt darüber, ob eine einzige HTTP/2-Verbindung kann zu Langsamkeit führen (Hervorhebung meiner):

Ist für die nahe Zukunft eine HTTP/2-Proxy-Unterstützung geplant?

Kurze Antwort:

Nein, es gibt keine Pläne.

Lange Antwort:

Die Implementierung ist praktisch sinnlos, da der Hauptvorteil von HTTP/2 darin besteht, dass viele Anforderungen innerhalb einer einzigen Verbindung gemultiplext werden können, wodurch die Begrenzung der Anzahl von gleichzeitigen Anforderungen [fast] aufgehoben wird - und es gibt keine solche Begrenzung, wenn mit Ihnen gesprochen wird Ihre eigenen Backends. Darüber hinaus kann es sogar noch schlimmer werden, wenn HTTP/2 für Backends verwendet wird, da eine einzelne TCP -Verbindung anstelle mehrerer verwendet wird.

Andererseits erfordert die Implementierung des HTTP/2-Protokolls und des Anforderungsmultiplexens innerhalb einer einzelnen Verbindung im Upstream-Modul wesentliche Änderungen am Upstream-Modul.

Aus diesen Gründen ist zumindest in absehbarer Zeit keine Implementierung von HTTP/2-Unterstützung im Upstream-Modul geplant. Wenn Sie immer noch der Meinung sind, dass eine Kommunikation mit Backends über HTTP/2 erforderlich ist, können Sie Patches bereitstellen.

Schließlich sollte auch angemerkt werden, dass Browser zwar HTTPS für HTTP/2 (h2) benötigen, die meisten Server dies jedoch nicht tun und diesen endgültigen Sprung über HTTP (h2c) unterstützen könnten. Eine durchgängige Verschlüsselung wäre also nicht erforderlich, wenn dies im Node) - Teil nicht vorhanden ist (wie dies häufig nicht der Fall ist). Dies hängt jedoch davon ab, wo sich der Back-End-Server im Verhältnis zum befindet Front-End-Server, der HTTPS auch für diese Verbindung verwendet, sollte möglicherweise in Betracht gezogen werden, wenn der Datenverkehr über ein ungesichertes Netzwerk übertragen wird (z. B. CDN an Origin-Server über das Internet).

47
Barry Pollard

NGINX unterstützt jetzt HTTP2/Push und es ist fantastisch ...

Hier drücke ich favicon.ico, minified.css, minified.js, register.svg, purchase_litecoin.svg auch von meiner statischen Subdomain. Es dauerte einige Zeit, bis mir klar wurde, dass ich von einer Subdomain aus Push ausführen kann.

location / {
            http2_Push_preload              on;
            add_header                      Link "<//static.yourdomain.io/css/minified.css>; as=style; rel=preload";
            add_header                      Link "<//static.yourdomain.io/js/minified.js>; as=script; rel=preload";
            add_header                      Link "<//static.yourdomain.io/favicon.ico>; as=image; rel=preload";
            add_header                      Link "<//static.yourdomain.io/images/register.svg>; as=image; rel=preload";
            add_header                      Link "<//static.yourdomain.io/images/purchase_litecoin.svg>; as=image; rel=preload";
            proxy_hide_header               X-Frame-Options;
            proxy_http_version              1.1;
            proxy_redirect                  off;
            proxy_set_header                Upgrade $http_upgrade;
            proxy_set_header                Connection "upgrade";
            proxy_set_header                X-Real-IP $remote_addr;
            proxy_set_header                Host $http_Host;
            proxy_set_header                X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header                X-Forwarded-Proto $scheme;
            proxy_pass                      http://app_service;
        }
6
indospace.io

NGINX unterstützt HTTP/2 nicht als Client. Da sie auf demselben Server laufen und es keine Latenz oder begrenzte Bandbreite gibt, denke ich nicht, dass dies einen großen Unterschied machen würde. Ich würde sicherstellen, dass Sie Keepalives zwischen nginx und node.js verwenden.

https://www.nginx.com/blog/tuning-nginx/#keepalive

6
Faisal Memon

Sie verlieren im Allgemeinen nicht an Leistung, da nginx dem Request-Multiplexing entspricht, das der Browser über HTTP/2 durch das Erstellen mehrerer gleichzeitiger Requests an Ihr Node-Backend durchführt. (Eine der größten Leistungsverbesserungen von HTTP/2 besteht darin, dass der Browser mehrere gleichzeitige Anforderungen über dieselbe Verbindung ausführen kann, wohingegen in HTTP 1.1 nur eine gleichzeitige Anforderung pro Verbindung möglich ist. Außerdem begrenzen die Browser die Anzahl der Verbindungen.)

3
Digitalkapitaen

Für den Fall, dass jemand nach einer Lösung dafür sucht, wenn es nicht bequem ist, Ihre Dienste HTTP2-kompatibel zu machen. Hier ist die grundlegende NGINX-Konfiguration, mit der Sie den HTTP1-Dienst in den HTTP2-Dienst konvertieren können.

server {
  listen [::]:443 ssl http2;
  listen 443 ssl http2;

  server_name localhost;
  ssl on;
  ssl_certificate /Users/xxx/ssl/myssl.crt;
  ssl_certificate_key /Users/xxx/ssl/myssl.key;

  location / {
    proxy_pass http://localhost:3001;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $Host;
  }
}
2
Sheng