Su cron de exportación de contabilidad se ejecuta "cada hora". Una mañana, contabilidad recibe dos expedientes idénticos con entradas duplicadas. Excavando: el trabajo de las 08:00 no había terminado cuando comenzó el trabajo de las 09:00: el mismo script, la misma tabla temporal, sin exclusión mutua.
En un solo VPS, es clásico. En una infraestructura en expansión, es peor: dos servidores ejecutan el mismo crontab porque nadie ha centralizado el programador.
¿Por qué se superponen los crons?
| Causa | Escenario | Síntoma |
|---|---|---|
| Trabajo demasiado largo | Importar > intervalo | Duplicados, puntos muertos DB |
| Reinicio manual | Administrador+cron | Dos procesos paralelos |
| Multiservidor | crontab copiado a 2 VPS | Doble facturación de clientes |
| Reintentar host | Tiempo de espera PHP matar + reiniciar | Compromiso parcial × 2 |
Un cron no es “idempotente” por defecto; hay que probarlo o bloquearlo.
grey: bloqueo de archivos en un solo host
* * * * * rebaño -n /var/lock/sync.lock /usr/local/bin/sync.sh >> /var/log/sync.log 2>&1
-n: sin bloqueo: omitir si se realiza el bloqueo (preferible a una cola infinita).- Bloqueo en disco local compartido si varios usuarios: no hay NFS inestable para bloqueos críticos.
Alternativa PHP:
$fp = fopen('/var/lock/job.lock', 'c');
si (!rebaño($fp, LOCK_EX | LOCK_NB)) {
salir(0);
}
// trabajo...
Bloqueo distribuido: Redis y PostgreSQL
Redis (patrón corto, se requiere TTL):
Bloqueo SET: exportar $(uuid) NX EX 3600
Libere con el script Lua compare-and-del para evitar eliminar el bloqueo de otro proceso.
Bloqueo de aviso de PostgreSQL: útil si el trabajo ya afecta a la base de datos:
SELECCIONE pg_try_advisory_lock(12345);
El bloqueo se libera al final de la sesión, lo que resulta útil para trabajos SQL prolongados.
Arquitectura: disparador cron versus trabajador único
Para trabajos pesados, cron solo colas:
- Minuto cron → insertar el ID del trabajo en la cola de Redis.
- Solo un consumidor trabajador procesa la cola.
- Visibilidad del tiempo de espera en el mensaje si falla.
Laravel Horizon, Sidekiq, Celery beat: el mismo principio. El cron se convierte en una llamada de atención, no en la ejecución en sí.
Monitoreo y registros
Inicio y fin del registro con PID, duración y estado. Correlacione con las métricas de la base de datos: los puntos muertos y las filas duplicadas suelen ser la primera señal. En compartido, verifique la zona horaria del servidor y los límites de PHP antes de enviar el código.
La cumbre: la idempotencia no reemplaza la cerradura, la complementa
Los dos juntos celebran la noche del Black Friday.
Decide y avanza sin puntos ciegos
Audite cada cron programado: compare la duración máxima observada con el intervalo configurado. Agregue Flock inmediatamente a cualquier VPS de un solo nodo. Centralice el programador si tiene varios servidores: un solo nodo cron o un bloqueo de Redis compartido. Registre el inicio y el final con PID para correlacionar duplicados. Consulte nuestra guía de hosting para conocer los límites de cron y PHP según la oferta.
Preguntas frecuentes
¿Es Flock suficiente para bloquear un cron bash?
Sí, en un solo servidor: Flock -n /var/lock/myjob.lock /path/script.sh evita una segunda instancia simultánea. El bloqueo desaparece si el proceso finaliza; verifique que el script no se bifurque sin liberar el bloqueo.
¿Cómo bloquear un cron en varios servidores?
Utilice un bloqueo distribuido: Redis SET NX EX, bloqueo de asesoramiento de PostgreSQL o bloqueo de DynamoDB. El rebaño no funciona entre máquinas.
¿Qué hacer si el trabajo anterior dura más que el intervalo cron?
Aumente el intervalo, permita omitir (flock -n que sale 0) o ponga en cola el trabajo (trabajador único). Nunca dejes que dos importaciones masivas se superpongan.
¿Los crons compartidos tienen dificultades específicas?
Sí: hora del servidor versus hora local, diferentes rutas de PHP, tiempo de espera de finalización silenciosa y múltiples nodos sin coordinación si el host escala la infraestructura sin avisarle.
Un cron sin candado es como la ruleta: un día la tarea termina dos veces, el día que no miras los registros.
