HTTP/2 ha llegado y aquí lo tienes funcionando

HTTP/2 se publicó de forma oficial en mayo de 2015, como RFC 7540. La semántica no ha cambiado respecto al viejo HTTP/1.1, pero HTTP/2 proporciona un mecanismo de transporte diferente con varias mejoras interesantes. En particular, se pueden multiplexar varias peticiones HTTP concurrentes a través de una única conexión TCP/IP. Esto reduce la latencia considerablemente mientras, de forma simultánea, se reduce la carga en el servidor.

Todos los navegadores modernos (incluyendo las versiones recientes de Android y de iOS) soportan HTTP/2. Bien. Más aún, Chrome y Firefox solo intentarán usar HTTP/2 cuando la conexión se realice de forma segura (HTTPS). Genial. Dado que HTTP/2 supone una mejora real pero simple de desplegar y que dicho despliegue supone migrar a HTTPS, esta jugada es -de hecho- un buen incentivo para que las webs migren a HTTPS.

La versión 2.4.17 de Apache HTTP Server incluye soporte de HTTP/2 de forma nativa. A fecha de hoy, esto requiere compilar Apache HTTP Server 2.4.17 o superior desde el código fuente y además:

  • Tener instalada una versión reciente de la librería Nghttp2.

  • Compilar Apache HTTP Server con la opción --enable-http2.

  • Si queremos servir HTTP/2 a través de HTTPS, que es lo deseable, tenemos que utilizar la versión 1.0.2 o superior de la librería OpenSSL.

    Esto es un problema porque muchas distribuciones Linux actuales aún están usando OpenSSL 1.0.1.

    Podemos servir HTTP/2 a través de HTTP normal y corriente y no necesitaríamos soporte OpenSSL, pero entonces navegadores como Chrome o Firefox no intentarán establecer conexiones HTTP/2 con nosotros.

Por supuesto, es de esperar que las futuras distribuciones de Linux incluyan de serie una versión de Apache HTTP Server compatible con HTTP/2. O sea, estos problemas no lo serán tanto dentro de un año.

Cuando tengamos un Apache HTTP Server con soporte HTTP/2, tenemos que activarlo:

 $ hg diff -c -1
 diff --git a/conf/httpd.conf b/conf/httpd.conf
 --- a/conf/httpd.conf
 +++ b/conf/httpd.conf
 @@ -90,6 +90,7 @@
  LoadModule mime_module         modules/mod_mime.so
  LoadModule dav_module          modules/mod_dav.so
  LoadModule status_module       modules/mod_status.so
 +LoadModule http2_module        modules/mod_http2.so
  LoadModule autoindex_module    modules/mod_autoindex.so
  LoadModule asis_module         modules/mod_asis.so
  LoadModule info_module         modules/mod_info.so
 @@ -123,6 +124,13 @@
  WSGIProcessGroup autenticacion_lmdb


 +<IfModule http2_module>
 +    LogLevel http2:info
 +
 +    # https://icing.github.io/mod_h2/howto.html
 +    Protocols h2 http/1.1
 +</IfModule>
 +
  <IfModule !mpm_winnt_module>
  <IfModule !mpm_netware_module>
  #
 @@ -281,8 +289,8 @@
      # a CustomLog directive (see below).
      #
      DeflateFilterNote deflate_ratio
 -    LogFormat "%h %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" In: %I Out: %O Time: %Dus mod_deflate: %{deflate_ratio}n pct." combined
 -    LogFormat "%h %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" In: %I Out: %O Time: %Dus mod_deflate: %{deflate_ratio}n pct. SSL: %{SSL_PROTOCOL}x %{SSL_CIPHER}x" combinedSSL
 +    LogFormat "%h %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" In: %I Out: %O Time: %Dus mod_deflate: %{deflate_ratio}n pct. %H" combined
 +    LogFormat "%h %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" In: %I Out: %O Time: %Dus mod_deflate: %{deflate_ratio}n pct. SSL: %{SSL_PROTOCOL}x %{SSL_CIPHER}x %H" combinedSSL
      #LogFormat "%h %l %u %t \"%r\" %>s %b" common

      <IfModule logio_module>

En la línea 9 cargamos el módulo HTTP/2. En las líneas 17-22 configuramos Apache HTTP Server para que active HTTP/2, pero solo bajo HTTPS. Si nos interesase activar HTTP/2 en las conexiones HTTP abiertas, ya he explicado por qué es mala idea, indicaríamos un protocolo h2c. Tienes más información en el artículo how to h2 in apache.

Las líneas 31-34 modifican la configuración de los ficheros de logs para que se guarde también si las conexiones van por HTTP/1.1 y HTTP/2. Por supuesto, este cambio es opcional. Me gusta guardarlo todo. Estadísticas, ya se sabe :-).

Una vez que hacemos estos cambios y reiniciamos Apache HTTP Server, bienvenido HTTP/2:

http2.png

Otro día hablaremos de la diferencia de rendimiento proporcionada por HTTP/2 en entornos reales.

Algunos enlaces adicionales que pueden interesaros: