Planificador de tareas en Go (Golang): de cron a asynq
En el desarrollo moderno de servidores con Go (Golang), a menudo surge la necesidad de ejecutar código según un horario o con un retraso. Limpieza de caché, envío de notificaciones, generación de informes: todo esto requiere un planificador de tareas confiable. En este artículo, analizaremos en detalle tres enfoques populares: el paquete estándar cron, la biblioteca ligera gocron y la cola distribuida asynq. Aprenderá qué herramienta elegir para su proyecto en PythonLib.
1. Cron estándar para Go
La biblioteca github.com/robfig/cron/v3 es el estándar de facto para programar tareas repetitivas en Go. Utiliza la sintaxis familiar de las expresiones cron (5 campos) y admite segundos, zonas horarias y recuperación de pánicos.
Instalación y ejemplo básico
go get github.com/robfig/cron/v3Ejemplo de un planificador que ejecuta una tarea cada 30 segundos:
package main
import ( "fmt" "github.com/robfig/cron/v3")
func main() { c := cron.New() // Agregamos una tarea con expresión cron: cada 30 segundos _, err := c.AddFunc("*/30 * * * * *", func() { fmt.Println("Tarea ejecutada:", time.Now()) }) if err != nil { panic(err) } c.Start() // Bloqueamos la gorutina main select {}}Características clave:
- Soporte para expresiones cron estándar (5 o 6 campos con segundos)
- Recuperación automática después de un pánico en la tarea
- Posibilidad de establecer la zona horaria mediante
cron.WithLocation() - Registro mediante
cron.WithLogger()
Uso avanzado: trabajos encadenados
c := cron.New(cron.WithSeconds())
// Tarea con nombre para gestiónid, _ := c.AddFunc("@every 5m", func() { fmt.Println("Se ejecuta cada 5 minutos")})
// Eliminación de tarea por IDc.Remove(id)
// Detención del planificadorc.Stop()La biblioteca es ideal para tareas periódicas simples dentro de un solo proceso. Sin embargo, para sistemas distribuidos (varias réplicas del servidor Go), se necesitará un bloqueo externo para evitar que la tarea se ejecute simultáneamente en todos los nodos.
2. Gocron: un scheduler ligero con cadenas
github.com/go-co-op/gocron ofrece una API más moderna sin expresiones cron. En lugar de cadenas, utiliza métodos encadenados. Esto es especialmente conveniente para principiantes.
Ejemplo con gocron
package main
import ( "fmt" "time" "github.com/go-co-op/gocron")
func main() { s := gocron.NewScheduler(time.UTC) // Tarea se ejecuta cada 2 minutos _, _ = s.Every(2).Minutes().Do(func() { fmt.Println("Han pasado 2 minutos") }) // Tarea con retraso después del inicio _, _ = s.Every(1).Day().At("10:30").Do(func() { fmt.Println("Diariamente a las 10:30") }) s.StartBlocking()}Ventajas de gocron:
- API legible para humanos:
.Every(10).Seconds() - Soporte integrado para bloqueos distribuidos mediante Redis (opcional)
- Posibilidad de establecer un límite en el número de ejecuciones
- Manejadores de errores globales y locales
Si necesita una solución simple para un microservicio sin dependencias externas, gocron será una excelente opción. Es más ligero que cron y no requiere conocer la sintaxis de las expresiones cron.
3. Asynq: cola distribuida de tareas retrasadas
github.com/hibiken/asynq no es solo un planificador, sino un sistema de colas completo basado en Redis. Permite retrasar tareas, establecer prioridades, reintentar tareas fallidas y rastrear su estado a través de una interfaz web.
Arquitectura de asynq
Asynq co