Systemd Timers vs. Cron: Elegir el programador adecuado

Compara cron y temporizadores de systemd para que puedas elegir el programador de Linux adecuado para trabajos simples, servicios, registro de eventos y dependencias.

Temporizadores de Systemd vs. Cron: Eligiendo el Programador Correcto

Cuando tu servidor Linux necesita ejecutar una copia de seguridad, limpieza, verificación de salud o informe en un horario programado, normalmente eliges entre cron y los temporizadores de systemd. Cron sigue siendo simple y portátil. Los temporizadores de systemd se adaptan mejor cuando el trabajo se comporta como un servicio gestionado y necesita registros, dependencias o controles de recursos.

La elección correcta depende de la máquina que ejecutas, el comportamiento del trabajo ante fallos y cuánta visibilidad operativa necesitas.

Entendiendo los Trabajos de Cron

cron es un programador de trabajos basado en tiempo en sistemas operativos tipo Unix. Permite a los usuarios programar comandos o scripts para que se ejecuten periódicamente en horas, fechas o intervalos fijos. El demonio cron (crond) se ejecuta en segundo plano y verifica los archivos crontab en busca de trabajos programados.

Cómo Funciona Cron

Cada usuario puede tener su propio archivo crontab, gestionado mediante el comando crontab. Los trabajos de todo el sistema se configuran típicamente en /etc/crontab o en archivos dentro de /etc/cron.d/.

Una entrada de crontab sigue un formato específico:

* * * * * comando_a_ejecutar
│ │ │ │ │
│ │ │ │ └───── Día de la semana (0 - 6) (Domingo=0 o 7)
│ │ │ └─────── Mes (1 - 12)
│ │ └───────── Día del mes (1 - 31)
│ └─────────── Hora (0 - 23)
└───────────── Minuto (0 - 59)

Ejemplo: Para ejecutar un script de copia de seguridad todos los días a las 2:00 AM:

0 2 * * * /usr/local/bin/backup.sh

Ventajas de Cron

  • Omnipresente: Disponible en prácticamente todos los sistemas tipo Unix.
  • Sintaxis Simple: El formato crontab es relativamente fácil de aprender para programación básica.
  • Trabajos Específicos de Usuario: Fácil de configurar trabajos para usuarios individuales.

Desventajas de Cron

  • Flexibilidad Limitada: Basado principalmente en intervalos de tiempo fijos. Manejar dependencias complejas o programación basada en eventos es difícil.
  • Sin Gestión de Dependencias: No puede definir fácilmente que un trabajo solo debe ejecutarse después de que otro trabajo se complete exitosamente.
  • Sin Control de Recursos: Ofrece poco o ningún control sobre los recursos (CPU, memoria) consumidos por los trabajos programados.
  • Registro y Monitoreo: A menudo depende de la salida de correo, syslog o redirección explícita en el comando.
  • Integración con Archivos de Unidad: No está directamente integrado con las capacidades de gestión de servicios de systemd.

Entendiendo los Temporizadores de Systemd

Los temporizadores de systemd son una forma más avanzada y flexible de programar tareas, aprovechando el poder de los archivos de unidad de systemd. En lugar de un demonio separado, los temporizadores de systemd se gestionan como parte del propio sistema de inicio systemd.

Cómo Funcionan los Temporizadores de Systemd

Los temporizadores de systemd constan de dos archivos de unidad:

  1. Unidad de Servicio (.service): Define la tarea o comando a ejecutar.
  2. Unidad de Temporizador (.timer): Define cuándo debe activarse la unidad de servicio correspondiente.

Estos archivos se colocan típicamente en /etc/systemd/system/ o ~/.config/systemd/user/.

Ejemplo: Programar un script de limpieza para que se ejecute diariamente a las 3:00 AM.

Primero, crea el archivo de servicio (cleanup.service):

# /etc/systemd/system/cleanup.service

[Unit]
Description=Tarea de limpieza diaria

[Service]
Type=oneshot
ExecStart=/usr/local/bin/cleanup.sh

A continuación, crea el archivo de temporizador (cleanup.timer):

# /etc/systemd/system/cleanup.timer

[Unit]
Description=Ejecutar tarea de limpieza diariamente

[Timer]
# Ejecutar 25 minutos después del arranque, y luego diariamente a las 3 AM
OnBootSec=25min
OnCalendar=*-*-* 03:00:00
# Alternativa: Ejecutar 24 horas después de la última ejecución
# OnUnitActiveSec=24h

[Install]
WantedBy=timers.target

Después de crear estos archivos, recarga systemd, habilita el temporizador para futuros arranques e inícialo ahora:

sudo systemctl daemon-reload
sudo systemctl enable cleanup.timer
sudo systemctl start cleanup.timer

Puedes verificar el estado del temporizador y cuándo se activará a continuación usando:

sudo systemctl status cleanup.timer

Directivas Clave del Temporizador de systemd:

  • OnCalendar=: Especifica una hora de evento de calendario (similar a la sintaxis de cron pero más potente).
    • *-*-* 03:00:00: Diariamente a las 3 AM.
    • Mon..Fri *-*-* 09:00:00: Días laborables a las 9 AM.
    • hourly: Cada hora.
    • daily: Una vez al día.
    • weekly: Una vez a la semana.
    • monthly: Una vez al mes.
    • yearly: Una vez al año.
  • OnBootSec=: Se activa un tiempo especificado después de que el sistema arranque.
  • OnUnitActiveSec=: Se activa un tiempo especificado después de que la unidad correspondiente (servicio) se haya activado por última vez.
  • OnUnitInactiveSec=: Se activa un tiempo especificado después de que la unidad correspondiente (servicio) se haya desactivado.
  • AccuracySec=: Qué tan preciso debe ser el temporizador. Valores más bajos pueden consumir más energía.
  • Persistent=: Para temporizadores de calendario, true le indica a systemd que se ponga al día cuando se perdió una ejecución programada mientras el temporizador estaba inactivo, por ejemplo, cuando la máquina estaba apagada.

Ventajas de los Temporizadores de Systemd

  • Integración con systemd: Se integra perfectamente con la gestión de servicios de systemd, el registro (journalctl), el control de recursos y la gestión de dependencias.
  • Flexibilidad: Soporta varias opciones de programación más allá de intervalos fijos, incluyendo eventos de calendario, tiempos relativos después del arranque y tiempos relativos después de la activación anterior.
  • Gestión de Dependencias: Puede definir dependencias en otras unidades de systemd (por ejemplo, disponibilidad de red).
  • Control de Recursos: Puede aprovechar los cgroups de systemd para limitar recursos (CPU, memoria).
  • Registro: Integrado con journald para un registro completo y centralizado.
  • Manejo de Errores: Puede usar el comportamiento de la unidad de servicio como Restart=, OnFailure= y orden de dependencia donde esos patrones se ajusten al trabajo.
  • Conciencia de Estado: Puede rastrear cuándo se suponía que un trabajo debía ejecutarse y ejecutarlo al iniciar el sistema si se establece Persistent=true.

Desventajas de los Temporizadores de Systemd

  • Curva de Aprendizaje más Pronunciada: La sintaxis y los conceptos de los archivos de unidad de systemd pueden ser más complejos que cron para principiantes.
  • Dependencia de Systemd: Requiere un sistema que ejecute systemd (la mayoría de las distribuciones modernas de Linux lo hacen).

Temporizadores de Systemd vs. Cron: Diferencias Clave Resumidas

Característica Trabajos de Cron Temporizadores de Systemd
Gestión Comando crontab, archivos del sistema Comando systemctl, archivos de unidad
Programación Minuto, hora, día, mes, día de semana fijos Eventos de calendario, tiempos relativos, basados en arranque
Integración Demonio independiente Integrado con systemd
Registro Correo, redirección de script journald
Dependencias Ninguna Dependencias de unidades de systemd
Control de Recursos Ninguno cgroups de systemd
Manejo de Errores Básico Manejo de fallos de unidad de servicio
Seguimiento de Estado Limitado Opción Persistent=
Complejidad Más simple para tareas básicas Más potente, curva de aprendizaje más pronunciada

Cuándo Elegir Cada Programador

Elige Cron Cuando:

  • Estás en un sistema muy antiguo o mínimo que no usa systemd.
  • Necesitas programar una tarea muy simple y única con un horario fijo y recurrente, y priorizas la simplicidad sobre las funciones avanzadas.
  • Necesitas un horario rápido para un comando que ya maneja su propio registro y errores.

Elige Temporizadores de Systemd Cuando:

  • Estás en una distribución moderna de Linux que usa systemd.
  • Necesitas más control sobre cuándo se ejecuta un trabajo (por ejemplo, relativo al arranque, relativo a la última ejecución, después de que la red esté activa).
  • Requieres un mejor registro, monitoreo y manejo de errores.
  • Deseas gestionar la ejecución de trabajos con las potentes funciones de gestión de servicios de systemd, incluyendo control de recursos y gestión de dependencias.
  • Ya estás gestionando otros servicios con systemd y deseas un enfoque consistente para la programación.
  • Tus tareas tienen dependencias de otros servicios o eventos del sistema.

Regla Práctica

Usa cron cuando el trabajo sea un comando corto y obvio y la portabilidad sea importante. Usa un temporizador de systemd cuando el trabajo sea parte de un servicio, necesite registros de journalctl, deba esperar la red, o se beneficie de límites de recursos y orden de dependencias.

Una copia de seguridad nocturna es un buen ejemplo. En un servidor heredado pequeño, 0 2 * * * /usr/local/bin/backup.sh puede ser suficiente. En un host de producción basado en systemd, un backup.service más backup.timer te da un estado más claro, registros, puesta al día de arranque con Persistent=true, y un camino más limpio para agregar dependencias más adelante.