Cómo hacer miles de redirecciones 301 en Nginx, tips de rendimiento

By aldibier, 28 Enero, 2018
Nginx, redirecciones, debian 8

Con la migración de un sitio Web desde un sistema a otro suele suceder que las rutas no quedan igual y se hace necesario hacer redirecciones 301 desde las URL's antiguas a las nuevas URL's para no afectar el SEO ya existente del sitio.

Para realizar las redirecciones se suele gestionar desde la nueva aplicación para que responda a las antiguas direcciones con un 301, sin embargo por practicidad y velocidad podríamos querer hacerlo desde nuestro servidor web y así no cargarle esa tarea al sistema de contenidos, ese fue el caso al que me enfrenté recientemente en donde el servidor web era un Nginx.

Investigando en la Web me di cuenta que la redirección mas veloz era una exacta usando la directiva location de Nginx, básicamente de la siguiente forma:

location /seccion/articulo-antiguo {

    return 301  /noticia/seccion/articulo-nuevo;

}

¿Fácil verdad?, bueno, en mi caso estábamos hablando de la necesidad de construir unas 65000 redirecciones así que para facilitar las cosas aproveché que tenía en base de datos el registro de la URL antigua frente a la nueva gracias al migrador que había implementado, me construí un archivo en php que tomó la información de la base de datos y me la arrojó en un archivo con todas las redirecciones en linea de la forma

location /seccion/articulo-antiguo {  return 301  /noticia/seccion/articulo-nuevo; }

El resultado final, un archivo que nombré redirects.conf con un tamaño de 16 MB, un mastodonte si tenemos en cuenta que es solo un archivo de configuración, sin embargo una vez entrara en funcionamiento el esfuerzo sería de Nginx y no del sistema de contenidos lo cual de por si ya era una gran ventaja.

El archivo lo almacené en la carpeta de nginx (En debian) /etc/nginx/snippets esa carpeta snippets la creé para tener todos los archivos de configuración a llamar cuando fuese necesario, luego en Nginx llamé al archivo desde dentro de la configuración del sitio de la forma:

include snippets/redirects.conf;

Al reiniciar Nginx me enfrenté a un gran problema, timeout de systemd por el tamaño del archivo, esperó minuto y medio y como no terminaba de leer el archivo arrojó timeout, esto significaba que debía aumentar el valor de ese timeout.

Para saber el tamaño del timeout actual se ejecuta el siguiente comando:

# systemctl show service -p TimeoutStartUSec

Con eso supe que era de minuto y medio, ajustarlo es sencillo, busque el archivo /etc/systemd/system.conf descomente y modifique la directiva DefaultTimeoutStartSec cambie a los segundos que prefiera, en mi caso puse 300 segundos, lo que equivale a 5 minutos.

Finalmente recargue las configuraciones de systemd con el siguiente comando

# systemctl daemon-reexec

Ahora si, reinicia nuevamente Nginx y paciencia.

Importante: Considero que no es tan buena idea dejar que este archivo sea un bloqueante para el inicio del servidor, debe existir alguna forma de hacer que esta configuración se cargue luego de iniciar el servidor Web y que el sitio responda, si no es así, entonces podŕian optar por mi solución, comentar la linea que incluye las redirecciones para cuando inicie el servidor lo haga rápido, luego se retira el comentario y se hace un reload de nginx para que cargue todo de nuevo, pero sin tumbar el servicio.