Cómo reducir latencia usando nginx como proxy

Cómo Reducir Latencia usando Nginx como Proxy

Cuando configuramos la infraestructura de La MIX Radio, el primer problema que apareció fue el retraso en el flujo de audio.
Notamos que el tiempo entre que lanzábamos un tema y el oyente lo escuchaba era demasiado alto. Para solucionar esto, decidimos reducir latencia usando Nginx como proxy delante de nuestro servidor Icecast.
No se trata de magia, sino de ajustar cómo el servidor maneja los paquetes de datos que viajan hacia el exterior.

El retraso en el streaming y por qué ocurre

Si dejas que Icecast gestione las conexiones directamente, el servidor puede saturarse rápidamente con peticiones HTTP simples.
Esto provoca que el flujo de audio se detenga o que el búfer del cliente se llene de forma ineficiente.
Cuando no configuramos un proxy adecuado, el servidor gasta recursos en tareas administrativas en lugar de empujar el audio lo más rápido posible.

Los síntomas son claros: el oyente experimenta cortes constantes o un retraso de varios segundos respecto al tiempo real.
En una radio de Deep House, donde el ritmo es constante, cualquier micro-corte es evidente.
Si no resolvemos esto, la experiencia del usuario cae drásticamente, aunque la calidad del audio sea la correcta. Esto nos llevó a buscar una forma de optimizar el camino que recorre el audio desde nuestra VM 111 hasta el navegador del usuario.

Lo que necesitamos antes de empezar

Para replicar lo que hacemos en nuestro homelab Proxmox, necesitas tener el entorno preparado. No intentes hacer esto sobre una instalación limpia sin haber probado primero la conexión básica.
Aquí tienes la lista de lo que usamos:

  • Un servidor con Debian o Ubuntu (nosotros usamos una VM en Proxmox).
  • Icecast instalado y funcionando en un puerto interno (por ejemplo, el 8000).
  • Nginx instalado y con permisos de administrador.
  • Acceso SSH al servidor para editar los archivos de configuración.
  • Un dominio apuntando a la IP de tu servidor.

Cómo lo resolvimos paso a paso

La clave para mejorar la respuesta del servidor es evitar que Nginx guarde el audio en un búfer interno antes de enviarlo. El audio es un flujo continuo; si Nginx intenta «almacenarlo» para optimizar el envío, solo añade retraso.
Primero, creamos un archivo de configuración específico para la radio en el directorio de sitios disponibles de Nginx.

El siguiente bloque de código define el servidor básico y cómo debe manejar las peticiones entrantes para redirigirlas al flujo de audio.

server {

listen 80;

server_name lamixradio.com;

# Redirigimos todo el tráfico HTTP a HTTPS por seguridad

location / {

return 301 https://$server_name$request_uri;
}
}

Una vez resuelta la redirección, pasamos a la configuración del puerto 443.
Aquí es donde ocurre la magia para reducir la latencia. Lo más importante es desactivar el proxy_buffering.
Si dejamos que Nginx haga buffering, el audio se acumula en el servidor y el oyente recibe el sonido en «bloques» en lugar de un chorro constante.

Utilizamos la siguiente configuración en nuestro bloque de servidor SSL para asegurar que el flujo sea inmediato.

server {

listen 443 ssl;

server_name lamixradio.com;

ssl_certificate /etc/letsencrypt/live/lamixradio.com/fullchain.pem;

ssl_certificate_key /etc/letsencrypt/live/lamixradio.com/privkey.pem;

location / {
# Enviamos la petición al puerto de Icecast en la VM 111

proxy_pass http://127.0.0.1:8000;

# Pasamos los encabezados originales para que Icecast reconozca al cliente

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

# Desactivamos el almacenamiento temporal para eliminar el lag

proxy_buffering off;

# Aumentamos el tiempo de espera para evitar cortes en streams largos

proxy_read_timeout 3600;

# Evitamos que Nginx intente comprimir el audio, que ya está comprimido

proxy_set_header Connection "keep-alive";
}
}

Después de aplicar estos cambios, reiniciamos el servicio para que Nginx tome la nueva configuración. En la práctica, descubrimos que el proxy_read_timeout es vital.
Si el valor es muy bajo, Nginx cierra la conexión pensando que el servidor Icecast dejó de responder, provocando que el reproductor del oyente tenga que reconectarse constantemente.

Para reducir latencia usando Nginx como proxy, el ajuste más crítico es proxy_buffering off. Sin esto, cualquier optimización de red es irrelevante porque el servidor retendrá los paquetes de audio.

Errores que nos costaron tiempo

No todo fue fluido. Durante la implementación en nuestro homelab, cometimos fallos que nos tuvieron despiertos hasta las 2 de la mañana. Estos fueron los tres más comunes:

Primero, dejamos el proxy_buffering activo por defecto.
El síntoma era que el audio tardaba hasta 10 segundos en empezar a sonar tras darle al play.
La causa era que Nginx esperaba llenar su búfer interno antes de enviar los datos. La solución fue añadir la directiva off explícitamente.

Segundo, tuvimos problemas con los permisos de los certificados SSL.
El servidor Nginx no arrancaba y dábamos errores 502. Resultó que los permisos de la carpeta de Let’s Encrypt eran demasiado restrictivos para el usuario de Nginx.
Lo solucionamos ajustando los permisos de lectura de las claves.

Tercero, configuramos un proxy_read_timeout muy corto (60 segundos).
El síntoma era que la radio se cortaba exactamente cada minuto. Descubrimos que Icecast mantiene la conexión abierta, pero Nginx la cerraba por inactividad aparente. Subimos el tiempo a 3600 segundos y el problema desapareció.

Cómo saber que funciona

Para verificar que hemos logrado reducir la latencia, no basta con escuchar la radio. Abrimos la consola del navegador (F12) en la pestaña «Network» y observamos la pestaña de «Timing».
Si el Time to First Byte (TTFB) es bajo y el flujo de datos es constante sin saltos bruscos en la gráfica de descarga, el proxy está haciendo su trabajo.

Además, comparamos el tiempo de inicio del stream con y sin el proxy configurado.
Notamos que la respuesta es casi instantánea, eliminando ese molesto silencio inicial que ocurre cuando el servidor está procesando la solicitud de manera ineficiente.

Qué sigue

Una vez que el flujo de audio es estable y rápido, el siguiente paso lógico es automatizar el monitoreo. En nuestro caso, implementamos un script en Python que revisa si el puerto 8000 de Icecast responde.
Si detecta una caída, envía una alerta inmediata a nuestro bot de Telegram para que podamos reiniciar el servicio en la VM 111 antes de que los oyentes noten la falla.

Compartir

“Post relacionados”