HeadlinesBriefing HeadlinesBriefing.com

Bessere HTTP/1-Verbindungswiederverwendung in Go

Hacker News •
×

Betrachten Sie diese Funktion, die eine GET-Anfrage an eine URL sendet und den HTTP-Statuscode zurückgibt. Bei Verwendung von HTTP/1 (GODEBUG=http2client=0) dauert der 100-malige Aufruf gegen index.golang.org auf der Maschine des Autors mit Go 1.26 etwa 710 Millisekunden. Mit Go 1.27 benötigt dasselbe Programm etwa 150 Millisekunden, also fast 5-mal schneller.

Der Unterschied ergibt sich aus den Kosten für den Verbindungsaufbau. Eine Anfrage über eine neue Verbindung erfordert einen TCP-Handshake (1 Round-Trip-Time, bzw. RTT), einen TLS-Handshake (2 RTT unter TLS 1.2) und anschließend die HTTP-Anfrage selbst, insgesamt etwa 3 RTT. Bei regionsübergreifender Kommunikation erreichen die Latenzen in eine Richtung häufig 50 ms oder mehr, sodass allein der Aufbau etwa 300 ms kosten kann. Selbst bei index.golang.org, das TLS 1.3 verwendet und eine vergleichsweise geringe Latenz bietet, ist das Öffnen einer neuen Verbindung deutlich spürbar.

Um diese Kosten zu vermeiden, versuchen HTTP-Clients und -Server, Verbindungen wiederzuverwenden. HTTP/1.0-Clients und -Server aktivieren dies mit dem Header Connection: keep-alive, während HTTP/1.1-Verbindungen standardmäßig persistent sind. HTTP/2 multiplext mehrere Anfragen und Antworten über eine einzige TCP-Verbindung.

In HTTP/1 kann die Wiederverwendung jedoch scheitern. Antworten auf derselben Verbindung werden nacheinander gesendet, daher kann net/http den Beginn der nächsten Antwort erst finden, wenn der Body der aktuellen Antwort vollständig gelesen wurde. Im Beispiel wird der Antwort-Body nie gelesen. Beim Aufruf von resp.Body.Close findet net/http also einen ungelesenen Body und kann die Verbindung nicht sicher wiederverwenden. Bis Go 1.26 erzwang dies für jede Anfrage eine neue Verbindung.

Quelle: Hacker News · Zusammengefasst von HeadlinesBriefing