Implementación de colas de trabajos con Supervisor para procesos en segundo plano

Los procesos en segundo plano y las colas de trabajos son esenciales para aplicaciones modernas que requieren tareas asíncronas, como envío de correos, generación de PDFs o procesamiento de imágenes. En esta guía técnica y práctica veremos cómo usar Supervisor como gestor de procesos para orquestar workers de colas, con ejemplos reales en Python y PHP, configuración recomendada, monitorización y buenas prácticas de producción.

¿Por qué usar Supervisor para gestionar workers?

Supervisor es un sistema de control de procesos que permite arrancar, detener y reiniciar programas en sistemas UNIX. Su ventaja frente a soluciones ad-hoc es la estabilidad operativa: autorestart, gestión de logs, control de grupos de procesos y una interfaz de control. Es especialmente útil cuando no deseas confiar únicamente en systemd o en scripts cron para mantener workers siempre activos.

Conceptos clave: colas de trabajos y workers

Una cola de trabajos desacopla la ejecución de tareas de la respuesta al usuario. Un worker consume mensajes de la cola y ejecuta la tarea. Para entender el concepto técnico puede consultarse la definición de cola (informática). Las colas pueden ser impulsadas por brokers como Redis, RabbitMQ o incluso bases de datos si la carga es moderada.

Patrón básico

  • Producer: agrega un job a la cola.
  • Broker: almacena el job (Redis, RabbitMQ, DB).
  • Worker: procesa jobs en segundo plano.

Arquitectura recomendada

En producción conviene separar responsabilidades: la aplicación web en front-end, el broker de la cola (p. ej. Redis en una instancia dedicada) y un clúster de workers detrás de Supervisor. Esto facilita escalado horizontal y control de recursos.

Instalación básica de Supervisor

En distribuciones Debian/Ubuntu Supervisor suele estar disponible en los repositorios. Un procedimiento típico:

sudo apt update
sudo apt install supervisor

En entornos virtuales o contenedores puedes instalarlo vía pip: pip install supervisor, pero en producción es preferible usar el paquete del sistema para integración con syslog y políticas de paquetes.

Configuración esencial de programas en Supervisor

Los archivos de configuración de Supervisor residen típicamente en /etc/supervisor/conf.d/ y terminan en .conf. Un ejemplo mínimo para un worker genérico:

[program:worker_name]
command=/usr/bin/python3 /srv/app/worker.py
directory=/srv/app
user=www-data
autostart=true
autorestart=true
startsecs=10
stdout_logfile=/var/log/worker_name/out.log
stderr_logfile=/var/log/worker_name/err.log
stopsignal=TERM
stopwaitsecs=10
environment=PYTHONUNBUFFERED='1'
numprocs=1
process_name=%(program_name)s_%(process_num)02d

Campos clave:

  • command: ruta completa y argumentos.
  • directory: directorio de trabajo para que los imports y dependencias funcionen.
  • user: ejecutar con usuario no root.
  • autostart/autorestart: mantener workers activos.
  • stdout_logfile/stderr_logfile: gestionar logs; integrar con logrotate.
  • numprocs y process_name: ejecutar múltiples procesos idénticos.

Ejemplo práctico 1: Python RQ + Supervisor

Redis Queue (RQ) es una opción sencilla para Python. Supongamos una app con virtualenv en /srv/app/venv y un worker que ejecuta rq worker default.

[program:rq_worker]
command=/srv/app/venv/bin/rq worker default
directory=/srv/app
user=appuser
autostart=true
autorestart=true
startsecs=10
stdout_logfile=/var/log/rq_worker/out.log
stderr_logfile=/var/log/rq_worker/err.log
numprocs=3
process_name=rq_worker_%(process_num)02d

Recomendaciones:

  • Crear un usuario dedicado (appuser) y asegurarse de permisos en /srv/app y /var/log.
  • Limitar numprocs según CPU y latencia: cada worker puede consumir memoria y conexiones Redis.
  • Configurar health checks externos que validen que el worker procesa jobs en un periodo esperado.

Ejemplo práctico 2: Laravel Queue Worker + Supervisor

En aplicaciones PHP con Laravel, el worker se ejecuta por consola: php artisan queue:work. Ejemplo de configuración:

[program:laravel_queue]
command=/usr/bin/php /srv/laravel/artisan queue:work --sleep=3 --tries=3
directory=/srv/laravel
user=www-data
autostart=true
autorestart=true
startsecs=5
stopsignal=QUIT
stdout_logfile=/var/log/laravel_queue/out.log
stderr_logfile=/var/log/laravel_queue/err.log
numprocs=2
process_name=laravel_queue_%(process_num)02d

Para PHP CLI es útil revisar la documentación oficial de PHP CLI y asegurarse de que las extensiones y variables de entorno estén presentes en el entorno donde corre el proceso.

Gestión de logs y rotación

Supervisor rota logs automáticamente si se configura, pero es mejor delegar en logrotate para mantener control y compresión. Un ejemplo de /etc/logrotate.d/worker:

/var/log/worker_name/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    copytruncate
}

Buenas prácticas operacionales

  • Ejecutar workers con usuarios limitados y separar permisos de lectura/escritura.
  • Usar entornos virtuales o contenedores y rutas absolutas en el campo command.
  • Definir stopsignal apropiado para permitir limpiezas ordenadas (SIGTERM/QUIT).
  • Monitorizar consumo de memoria y CPU; reiniciar procesos si alcanzan límites razonables.
  • Configurar startsecs y startretries: startsecs para evitar reinicios en arranques temporales.

Tuning y escalado

Para cargas variables combina:

  • Escalado vertical: aumentar numprocs por máquina hasta saturación de CPU/memoria.
  • Escalado horizontal: desplegar más instancias con Supervisor en diferentes hosts o usar orquestadores como Kubernetes para gestionar pods.
  • Ajuste del broker: por ejemplo, si usas Redis, monitoriza latency y conexiones; si usas DB-backed queues, vigila índices.

Monitorización y alertas

Integra métricas y alertas: número de jobs pendientes, tasa de errores por worker, promedio de latencia. Puedes exponer métricas desde tu aplicación o usar herramientas de proceso que checkeen el estado de Supervisor mediante supervisorctl or la API XML-RPC. Para el servidor web y límites de concurrencia sirve revisar configuración de NGINX y parámetros de sistema como ulimit.

Seguridad y consideraciones de red

  • Evita exponer interfaces de administración sin autenticación. Si usas la interfaz web de Supervisor, protégela con firewall y autenticación.
  • Configura variables de entorno sensibles mediante archivos protegidos o gestores de secretos, no en supervisor.conf en texto plano.
  • Controla la comunicación entre workers y broker con TLS si procede.

Comparativa: Supervisor vs systemd y alternativas

systemd ofrece capacidades de gestión de servicios nativas y es adecuado para infraestructuras modernas; sin embargo, Supervisor suele ser más sencillo de usar para desarrolladores por su formato simple y por agrupar programas en directorios de conf. Para despliegues en contenedores o Kubernetes se prefieren orquestadores que gestionen ciclo de vida de pods y autoescalado.

Errores comunes y cómo evitarlos

  • No usar rutas absolutas en command: provoca fallos al arrancar en entorno distinto.
  • Permisos incorrectos en directorios de logs o PID: el proceso no puede escribir y el reinicio falla.
  • Ignorar la salud del broker: workers consumen muy lento si Redis está saturado.
  • No separar entornos: usar variables de entorno de prod en dev puede generar fugas de datos.

Checklist antes de producción

  • Pruebas de carga en workers y broker.
  • Políticas de logging y rotación funcionando.
  • Health checks y alertas configuradas.
  • Backups y recuperación del broker si es persistente.
  • Documentación de comandos de supervisorctl para el equipo de operaciones.

Conclusión

Supervisor es una solución sólida y pragmática para gestionar workers de colas en entornos tradicionales. Su facilidad de configuración, capacidades de autorestart y agrupación de procesos lo hacen ideal para mantener procesos en segundo plano estables. Combinado con un broker adecuado, monitorización y buenas prácticas de seguridad, permite construir pipelines de procesamiento robustos y escalables. Para cargas más dinámicas o despliegues en la nube, evalúa orquestadores como Kubernetes como alternativa a gran escala, pero para la mayoría de infraestructuras web, Supervisor sigue siendo una herramienta eficiente y fiable.