Планировщик задач на Go (Golang): от простого ticker до промышленного cron
Планировщик задач (task scheduler) — это компонент, который позволяет выполнять определённые функции в заданное время или с заданной периодичностью. В экосистеме Go (Golang) существует несколько подходов к реализации планировщика: от встроенных примитивов языка до мощных сторонних библиотек. В этой статье мы разберём, как создать планировщик задач на Go, начиная с простых примеров и заканчивая использованием популярной библиотеки robfig/cron.
Зачем нужен планировщик задач в Go?
Go идеально подходит для создания высокопроизводительных серверных приложений, микросервисов и утилит командной строки. Планировщик задач позволяет автоматизировать рутинные операции:
- Очистка кэша или временных файлов
- Отправка периодических уведомлений (email, SMS)
- Сбор метрик и мониторинг
- Синхронизация данных с внешними API
- Генерация отчётов по расписанию
Базовый планировщик с использованием time.Ticker
Самый простой способ выполнять задачу каждые N секунд — использовать time.Ticker. Этот встроенный инструмент Go отправляет значение в канал через заданные интервалы времени.
package main
import (
"fmt"
"time"
)
func main() {
ticker := time.NewTicker(2 * time.Second)
done := make(chan bool)
go func() {
for {
select {
case <-ticker.C:
fmt.Println("Задача выполнена:", time.Now().Format(time.RFC3339))
case <-done:
ticker.Stop()
return
}
}
}()
// Остановим планировщик через 10 секунд
time.Sleep(10 * time.Second)
done <- true
fmt.Println("Планировщик остановлен")
}
Этот код создаёт горутину, которая каждые 2 секунды выводит текущее время. Обратите внимание на использование select — это ключевой паттерн Go для неблокирующей обработки нескольких каналов.
Планировщик с гибким расписанием: библиотека robfig/cron
Для реальных проектов, где требуется cron-подобное расписание (например, «каждый понедельник в 9:00» или «каждые 5 минут с 9 до 18»), лучше всего подходит библиотека github.com/robfig/cron/v3. Она полностью поддерживает стандартный синтаксис cron и добавляет удобные функции, такие как работа с часовыми поясами и обработка паник.
Установка
go get github.com/robfig/cron/v3
Пример использования
package main
import (
"fmt"
"log"
"time"
"github.com/robfig/cron/v3"
)
func main() {
c := cron.New(cron.WithSeconds()) // Включаем поддержку секунд
// Добавляем задачу: каждые 10 секунд
_, err := c.AddFunc("*/10 * * * * *", func() {
fmt.Println("Задача 1: каждые 10 секунд", time.Now().Format(time.RFC3339))
})
if err != nil {
log.Fatal(err)
}
// Задача: каждый день в 14:30 по UTC
_, err = c.AddFunc("0 30 14 * * *", func() {
fmt.Println("Задача 2: ежедневно в 14:30 UTC")
})
if err != nil {
log.Fatal(err)
}
// Задача с именем для последующего управления
entryID, _ := c.AddFunc("@every 1m", func() {
fmt.Println("Задача 3: каждую минуту")
})
c.Start()
// Удаляем задачу через 5 минут
time.Sleep(5 * time.Minute)
c.Remove(entryID)
fmt.Println("Задача 3 удалена")
// Блокируем main
select {}
}
Библиотека поддерживает несколько форматов расписания:
- Стандартный cron:
"30 * * * *"— каждые 30 минут - С секундами:
"0 30 * * * *"— в 30 секунд каждой минуты - @every:
"@every 5m"— каждые 5 минут - @daily, @weekly, @monthly — предопределённые интервалы
Продвинутый планировщик с контекстом и отменой
В production-среде важно корректно завершать работу планировщика. Используйте context.Context для graceful shutdown:
package main
import (
"context" Также в библиотеке
Авторизация и аутентификация в Kotlin: JWT, Spring Security и Ktor
Геолокация и карты в TypeScript: библиотеки и практические примеры