Планировщик задач на Go (Golang): cron, gocron и robfig/cron
Планировщик задач (task scheduler) — это незаменимый инструмент для автоматизации периодических операций в приложениях: от очистки кэша и отправки уведомлений до запуска фоновых обработчиков данных. В экосистеме Go (Golang) существует несколько популярных библиотек для реализации cron-подобного поведения. В этой статье мы рассмотрим три основных подхода: встроенный пакет cron, легковесный gocron и де-факто стандарт robfig/cron.
1. Встроенный пакет cron (экспериментальный)
Начиная с Go 1.19, в стандартной библиотеке появился экспериментальный пакет cron в golang.org/x/exp/cron. Он предоставляет базовый функционал для запуска задач по расписанию. Однако на практике он используется редко из-за ограниченной функциональности и отсутствия поддержки сложных cron-выражений (например, с секундами).
package main
import (
"context"
"fmt"
"golang.org/x/exp/cron"
"time"
)
func main() {
sched := cron.New()
// Запуск каждые 10 секунд
sched.Add("*/10 * * * * *", func() {
fmt.Println("Задача выполнена:", time.Now())
})
sched.Start()
time.Sleep(30 * time.Second)
sched.Stop()
}
2. Библиотека robfig/cron — золотой стандарт
Библиотека github.com/robfig/cron/v3 является самой популярной и зрелой реализацией планировщика задач на Go. Она поддерживает:
- Стандартные cron-выражения (5 полей) с опциональным полем секунд
- Предопределённые расписания:
@yearly,@monthly,@weekly,@daily,@hourly - Интервалы:
@every 5m(каждые 5 минут) - Часовые пояса (timezone)
- Обработку паник через Recovery логгер
- Гибкую систему логгирования через интерфейс
Logger
Установка
go get github.com/robfig/cron/v3
Базовый пример
package main
import (
"fmt"
"github.com/robfig/cron/v3"
"time"
)
func main() {
c := cron.New(cron.WithSeconds()) // Включаем поддержку секунд
// Каждую минуту в 30 секунд
c.AddFunc("30 * * * * *", func() {
fmt.Println("Каждую минуту в 30 секунд:", time.Now().Format("15:04:05"))
})
// Каждый день в 8:00 утра
c.AddFunc("0 0 8 * * *", func() {
fmt.Println("Ежедневно в 8:00")
})
// Каждые 2 часа
c.AddFunc("@every 2h", func() {
fmt.Println("Каждые 2 часа")
})
// Понедельник в 9:30
c.AddFunc("30 9 * * 1", func() {
fmt.Println("Каждый понедельник в 9:30")
})
c.Start()
defer c.Stop()
// Ждём 1 минуту, чтобы увидеть выполнение
time.Sleep(70 * time.Second)
}
Синтаксис cron-выражений в robfig/cron
Стандартное выражение состоит из 5 полей (минуты, часы, день месяца, месяц, день недели). При включении опции cron.WithSeconds() добавляется шестое поле — секунды (0-59).
*— любое значение*/5— каждые 5 единиц1,15,30— конкретные значения1-10— диапазонL— последний (например, последний день месяца)
3. Библиотека gocron — простота и читаемость
github.com/go-co-op/gocron предлагает более высокоуровневый, fluent-интерфейс для создания расписаний. Она идеально подходит, если вам не нужны сложные cron-выражения, а достаточно простых интервалов.
Установка
go get github.com/go-co-op/gocron/v2
Пример использования
package main
import (
"fmt