HeadlinesBriefing HeadlinesBriefing.com

Meilleure réutilisation des connexions HTTP/1 en Go

Hacker News •
×

Prenons cette fonction, qui envoie une requête GET à une URL et renvoie le code de statut HTTP. En utilisant HTTP/1 (GODEBUG=http2client=0), l'appeler 100 fois sur index.golang.org prend environ 710 millisecondes avec Go 1.26 sur la machine de l'auteur. Avec Go 1.27, le même programme prend environ 150 millisecondes, soit près de 5 fois plus rapide.

L'écart provient du coût d'établissement des connexions. Faire une requête sur une nouvelle connexion nécessite une poignée de main TCP (1 temps aller-retour, ou RTT), une poignée de main TLS (2 RTT avec TLS 1.2), puis la requête HTTP elle-même, soit au total environ 3 RTT. Dans les communications inter-régionales, les latences à sens unique atteignent souvent ou dépassent 50 ms, si bien que la seule mise en place peut coûter environ 300 ms. Même avec index.golang.org, qui utilise TLS 1.3 et offre une latence relativement faible, l'ouverture d'une nouvelle connexion reste très perceptible.

Pour éviter ce coût, les clients et serveurs HTTP tentent de réutiliser les connexions. Les clients et serveurs HTTP/1.0 y consentent avec un en-tête Connection: keep-alive, tandis que les connexions HTTP/1.1 sont persistantes par défaut. HTTP/2 multiplexe plusieurs requêtes et réponses sur une seule connexion TCP.

La réutilisation peut toutefois échouer en HTTP/1. Les réponses sur une même connexion sont envoyées séquentiellement, donc net/http ne peut localiser le début de la réponse suivante qu'une fois le corps de la réponse courante lu jusqu'au bout. Dans l'exemple, le corps de la réponse n'est jamais lu : lorsque resp.Body.Close est appelé, net/http trouve un corps non lu et ne peut pas réutiliser la connexion en toute sécurité. Jusqu'à Go 1.26, cela imposait une nouvelle connexion pour chaque requête.

Source: Hacker News · Résumé par HeadlinesBriefing