Очереди задач в Go (Golang): лучшие библиотеки и инструменты

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Очереди задач для Go (Golang): полное руководство по библиотекам и инструментам

В мире современной разработки на Go (Golang) обработка фоновых задач и асинхронных операций — критически важная задача. Будь то отправка email, генерация отчетов, обработка изображений или взаимодействие с внешними API, очереди задач (task queues) позволяют разгрузить основной поток приложения и повысить его отказоустойчивость. В этой статье мы рассмотрим лучшие библиотеки для работы с очередями в Go, их особенности и примеры использования.

Что такое очередь задач и зачем она нужна?

Очередь задач — это механизм, который позволяет откладывать выполнение ресурсоемких или длительных операций на фоне. Основные преимущества:

  • Асинхронность: пользователь не ждет завершения тяжелой операции.
  • Масштабирование: вы можете запускать множество воркеров для параллельной обработки.
  • Отказоустойчивость: если воркер упал, задача остается в очереди и будет выполнена другим.
  • Планирование: отложенный запуск задач (например, через 1 час).

Топ-3 библиотеки для очередей задач в Go

1. Asynq

Asynq — современная, производительная и простая в использовании библиотека для распределенных очередей задач, построенная на Redis. Разработана командой Google и активно поддерживается сообществом.

Ключевые особенности:

  • Работает поверх Redis (рекомендуется версия 6.0+).
  • Поддержка отложенных задач (scheduled tasks).
  • Встроенный веб-интерфейс для мониторинга (Asynqmon).
  • Dead-letter очередь для упавших задач.
  • Группы задач (task groups) для логической группировки.
  • Retry с настраиваемой политикой повторных попыток.

Пример использования:

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "github.com/hibiken/asynq"
)

// Определяем тип задачи
const TypeEmailDelivery = "email:deliver"

// Структура данных для задачи
type EmailTaskPayload struct {
    UserID     int
    TemplateID string
}

// Обработчик задачи
func HandleEmailTask(ctx context.Context, t *asynq.Task) error {
    var payload EmailTaskPayload
    if err := json.Unmarshal(t.Payload(), &payload); err != nil {
        return fmt.Errorf("json.Unmarshal failed: %v: %w", err, asynq.SkipRetry)
    }
    log.Printf("Sending email to user %d with template %s", payload.UserID, payload.TemplateID)
    // Здесь логика отправки email
    return nil
}

func main() {
    // Клиент для постановки задач
    client := asynq.NewClient(asynq.RedisClientOpt{Addr: "localhost:6379"})
    defer client.Close()

    // Создаем задачу
    payload, _ := json.Marshal(EmailTaskPayload{UserID: 42, TemplateID: "welcome"})
    task := asynq.NewTask(TypeEmailDelivery, payload, asynq.MaxRetry(5))

    // Ставим задачу в очередь
    info, err := client.Enqueue(task, asynq.ProcessIn(10*time.Second)) // отложить на 10 сек
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("Task enqueued: ID=%s, Queue=%s", info.ID, info.Queue)

    // Сервер-воркер
    srv := asynq.NewServer(
        asynq.RedisClientOpt{Addr: "localhost:6379"},
        asynq.Config{Concurrency: 10},
    )

    // Регистрируем обработчик
    mux := asynq.NewServeMux()
    mux.HandleFunc(TypeEmailDelivery, HandleEmailTask)

    // Запускаем воркер
    if err := srv.Run(mux); err != nil {
        log.Fatal(err)
    }
}

2. Machinery

Machinery — одна из самых популярных и зрелых библиотек для Go. Поддерживает несколько брокеров: Redis, AMQP (RabbitMQ), AWS SQS, MongoDB и другие. Отличается богатой функциональностью и гибкостью.

Ключевые особенности:

  • Поддержка множества брокеров и хранилищ результатов.
  • Цепочки задач (chains) — выполнение задач последовательно.
  • Группы задач (groups) — параллельное выполнение.
  • Планирование (cron) — периодические задачи.
  • Мониторинг через веб-интерфейс Flower.
  • Поддержка отложенных задач (ETA).

Пример использования:

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/RichardKnox/machinery/v1"                    

Рекомендаций