HeadlinesBriefing HeadlinesBriefing.com

Mejor reutilización de conexiones HTTP/1 en Go

Hacker News •
×

Considere esta función, que envía una solicitud GET a una URL y devuelve el código de estado HTTP. Usando HTTP/1 (GODEBUG=http2client=0), llamarla 100 veces contra index.golang.org tarda unos 710 milisegundos en Go 1.26 en la máquina del autor. En Go 1.27, el mismo programa tarda unos 150 milisegundos, casi 5 veces más rápido.

La diferencia proviene del costo de establecer conexiones. Hacer una solicitud por una conexión nueva requiere un handshake TCP (1 tiempo de ida y vuelta, o RTT), un handshake TLS (2 RTT con TLS 1.2) y luego la propia solicitud HTTP, para un total de unos 3 RTT. En comunicaciones entre regiones, las latencias de un sentido suelen alcanzar o superar los 50 ms, así que solo la configuración puede costar unos 300 ms. Incluso con index.golang.org, que usa TLS 1.3 y ofrece una latencia relativamente baja, abrir una conexión nueva sigue siendo muy notable.

Para evitar este costo, los clientes y servidores HTTP intentan reutilizar conexiones. Los clientes y servidores HTTP/1.0 lo activan con una cabecera Connection: keep-alive, mientras que las conexiones HTTP/1.1 son persistentes por defecto. HTTP/2 multiplexa varias solicitudes y respuestas sobre una única conexión TCP.

Sin embargo, la reutilización puede fallar en HTTP/1. Las respuestas en la misma conexión se envían de forma secuencial, por lo que net/http solo puede localizar el inicio de la siguiente respuesta cuando el cuerpo de la respuesta actual se ha leído por completo. En el ejemplo, el cuerpo de la respuesta nunca se lee, así que al llamar a resp.Body.Close, net/http encuentra un cuerpo sin leer y no puede reutilizar la conexión de forma segura. Hasta Go 1.26, esto obligaba a crear una nueva conexión para cada solicitud.

Fuente: Hacker News · Resumido por HeadlinesBriefing