Appearance
Background Jobs — Deployment & Operations
Aplica a: Fases 1-3 (producción)
Prerequisitos
| Requisito | Detalle |
|---|---|
| Supervisor | Instalado en el servidor (supervisord disponible en PATH) |
| Cron | Disponible en el servidor (crontab -e funcional) |
| PHP | /usr/bin/php accesible por el usuario que corre el worker |
| Usuario | www-data (o equivalente con acceso al directorio del proyecto) |
| Logs directory | {PROJECT_ROOT}/logs/ creado y con permisos de escritura para www-data |
Instalar Supervisor
bash
# Ubuntu/Debian
sudo apt install supervisor
# CentOS/RHEL
sudo yum install supervisorProcesos a gestionar
| Proceso | Tipo | Propósito |
|---|---|---|
bin/worker.php | Daemon long-running (Supervisor) | Heartbeat, safety-net retry (5 min), stale cleanup en tiempo real |
cli/cleanup-stale-jobs.php --days=30 | Tarea periódica diaria (Crontab) | Elimina jobs con más de 30 días de antigüedad |
Nota sobre retries: El mecanismo principal de retry es el self-dispatch dentro de
JobExecutor: al fallar un job con reintentos disponibles, el executor re-despacha el worker CLI directamente. El daemonbin/worker.phpactúa como safety-net con un intervalo de 5 minutos, reintentando jobs pendientes cuyo self-dispatch pudo haber fallado (ej: proceso terminado antes de completar el dispatch). El archivoretry-scheduler.phpfue eliminado; ya no se depende de cron para scheduling de retries.
Variables de Entorno Requeridas
El worker lee la configuración desde {PROJECT_ROOT}/.env:
env
DB_HOST=localhost
DB_PORT=5432
DB_NAME=empresa_xyz
DB_USER=postgres
DB_PASS=secret
ENABLE_BACKGROUND_JOBS=trueConfiguración de Supervisor
Plantilla provista por el proyecto
El proyecto incluye supervisor/bautista-worker.conf.dist con {PROJECT_ROOT} como placeholder. Copiarla y reemplazar el placeholder antes de activar:
bash
cp {PROJECT_ROOT}/supervisor/bautista-worker.conf.dist /etc/supervisor/conf.d/bautista-worker.confReemplazar {PROJECT_ROOT} en el archivo copiado con la ruta absoluta real del proyecto (por ejemplo /var/www/mi-proyecto).
Contenido del archivo de configuración
ini
[program:bautista-worker]
command=/usr/bin/php {PROJECT_ROOT}/bin/worker.php
directory={PROJECT_ROOT}
user=www-data
autostart=true
autorestart=true
startretries=5
startsecs=3
stopwaitsecs=10
redirect_stderr=true
stdout_logfile={PROJECT_ROOT}/logs/background-jobs.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=5
environment=APP_ENV="production"Aplicar la configuración
bash
# Recargar configuración de Supervisor
sudo supervisorctl reread
sudo supervisorctl update
# Verificar que el worker arrancó
sudo supervisorctl status bautista-workerConfiguración de Crontab
La limpieza periódica se configura como una línea de crontab bajo el usuario www-data:
bash
sudo crontab -u www-data -eAgregar la siguiente línea (reemplazar {PROJECT_ROOT} con la ruta absoluta real):
bash
0 2 * * * /usr/bin/php {PROJECT_ROOT}/cli/cleanup-stale-jobs.php --days=30 >> {PROJECT_ROOT}/logs/cleanup.log 2>&1El cleanup se ejecuta todos los días a las 02:00. La salida (stdout y stderr) se acumula en logs/cleanup.log.
Comandos Operacionales
Estado y control del worker
bash
# Ver estado del worker
sudo supervisorctl status bautista-worker
# Reiniciar el worker (obligatorio después de cada deploy)
sudo supervisorctl restart bautista-worker
# Detener el worker
sudo supervisorctl stop bautista-worker
# Iniciar el worker manualmente
sudo supervisorctl start bautista-workerLogs del worker
bash
# Ver log en tiempo real
tail -f {PROJECT_ROOT}/logs/background-jobs.log
# Ver últimas 100 líneas
tail -n 100 {PROJECT_ROOT}/logs/background-jobs.log
# Debug via Supervisor (stderr capturado junto a stdout)
sudo supervisorctl tail bautista-worker stderrCleanup manual
bash
# Simulación sin eliminar (dry-run)
/usr/bin/php {PROJECT_ROOT}/cli/cleanup-stale-jobs.php --days=30 --dry-run
# Ejecución real
/usr/bin/php {PROJECT_ROOT}/cli/cleanup-stale-jobs.php --days=30Manejar jobs fallidos via API
bash
# Listar jobs fallidos
GET /jobs?status=failed
# Retry manual de un job específico
POST /jobs/{id}/retryVerificación de Salud
Después del setup inicial, confirmar que todo está corriendo:
bash
# 1. Supervisor reporta el worker como RUNNING
sudo supervisorctl status bautista-worker
# Resultado esperado: bautista-worker RUNNING pid 12345, uptime 0:01:23
# 2. Log del worker tiene actividad reciente
tail -n 20 {PROJECT_ROOT}/logs/background-jobs.log
# 3. Health check HTTP (requiere servidor corriendo)
curl http://localhost/jobs/health
# 4. Verificar que el crontab está configurado para www-data
sudo crontab -u www-data -lApagado Graceful
El daemon bin/worker.php maneja SIGTERM limpiamente: termina la iteración en curso antes de detenerse. Supervisor envía SIGTERM al detener el proceso y espera hasta stopwaitsecs=10 antes de forzar SIGKILL.
bash
# Detener limpiamente (Supervisor envía SIGTERM, espera 10s)
sudo supervisorctl stop bautista-worker
# Verificar que se detuvo
sudo supervisorctl status bautista-worker
# Resultado esperado: bautista-worker STOPPEDMonitoreo Prometheus
El endpoint /jobs/metrics expone métricas en formato Prometheus:
bautista_jobs_total{status="completed"} 1423
bautista_jobs_total{status="failed"} 12
bautista_jobs_total{status="running"} 2
bautista_jobs_total{status="pending"} 5
bautista_jobs_p95_duration_seconds 47.2Agregar al prometheus.yml:
yaml
scrape_configs:
- job_name: bautista-background-jobs
static_configs:
- targets: ['localhost:80']
metrics_path: /jobs/metricsÚltima actualización: 2026-03-12