Реализация рабочих процессов с помощью Temporal на Go: полное руководство

Создание рабочих процессов на Go с помощью Temporal SDK

Содержимое страницы

Temporal — это open-source воркфлоу-движок корпоративного уровня, который позволяет разработчикам создавать надежные, масштабируемые и отказоустойчивые приложения для управления бизнес-процессами, используя знакомые языки программирования, такие как Go.

Распределенные приложения со сложными переходами состояний и повторными попытками требуют надежного фреймворка оркестрации.

Это руководство объясняет, как реализовать приложения для управления бизнес-процессами с помощью Temporal в Go, охватывая конфигурацию, примеры кода, стратегии развертывания, лучшие практики и устранение неполадок.

Go Workplace

Что такое Temporal и зачем использовать его с Go

Temporal — это фреймворк оркестрации рабочих процессов, предназначенный для создания отказоустойчивых распределенных приложений с длительным временем выполнения. Temporal управляет состоянием, повторными попытками, таймерами и восстановлением после сбоев в фоновом режиме, позволяя разработчикам сосредоточиться на логике приложения без необходимости писать шаблонный код оркестрации. Он поддерживает Go (среди других языков) через Temporal Go SDK.

Использование Temporal с Go дает следующие преимущества:

  • Рабочие процессы являются надежными и воспроизводимыми.
  • Повторные попытки и таймауты активностей обрабатываются автоматически.
  • Состояние системы сохраняется при сбоях.
  • Логика оркестрации задач реализована в идиоматичном коде на Go.

Основные понятия: рабочие процессы, активности, воркеры

Прежде чем создать свое первое приложение Temporal на Go, ознакомьтесь с этими ключевыми понятиями:

Рабочие процессы (Workflows)

Рабочий процесс — это логика координации, которая вызывает активности. Она должна быть детерминированной — движок Temporal может надежно воспроизводить ее. В Go рабочие процессы представляют собой обычные функции Go со специальным параметром workflow.Context.

Активности (Activities)

Активности — это единицы работы, содержащие недетерминированные операции (ввод/вывод, вызовы внешних API). Активности выполняются вне рабочего процесса и возвращают результаты обратно в логику рабочего процесса.

Воркеры (Workers)

Воркер — это хост, который запускает функции рабочих процессов и активностей. Воркеры опрашивают очереди задач сервера Temporal и обрабатывают задачи. Они должны зарегистрировать рабочие процессы и активности перед запуском.

Очереди задач (Task Queues)

Очередь задач — это механизм, с помощью которого воркер получает задачи от сервера Temporal. Рабочие процессы и активности указывают имя очереди задач, которую они будут использовать.


Настройка проекта Go с Temporal

Предварительные требования

  • Go (1.16+)
  • Сервер Temporal (локальный или облачный)
  • Docker (для локального сервера)
  • Зависимость go.temporal.io/sdk

Установка Temporal Go SDK

go get go.temporal.io/sdk

Запуск сервера разработки Temporal

Для локальной разработки:

docker run -d --network host temporalio/temporal-server

Или используйте CLI Temporal:

temporal server start-dev

По умолчанию это запускает сервер Temporal и веб-интерфейс.


Конфигурация: клиенты и очереди задач

Создание клиента Temporal

c, err := client.NewClient(client.Options{
    HostPort: "localhost:7233",
})
if err != nil {
    log.Fatal(err)
}
defer c.Close()

Выбор очереди задач

Определите уникальную очередь задач для вашего воркера:

const TaskQueue = "order-processing-queue"

Воркеры и инициаторы рабочих процессов должны использовать одно и то же имя очереди задач.


Примеры на Go: рабочие процессы и активности

Определение простого рабочего процесса

func SampleWorkflow(ctx workflow.Context, input string) (string, error) {
    ao := workflow.ActivityOptions{
        TaskQueue:           TaskQueue,
        ScheduleToCloseTimeout: time.Minute,
    }
    ctx = workflow.WithActivityOptions(ctx, ao)

    var result string
    err := workflow.ExecuteActivity(ctx, SampleActivity, input).Get(ctx, &result)
    if err != nil {
        return "", err
    }
    return result, nil
}

Определение активности

func SampleActivity(ctx context.Context, message string) (string, error) {
    return fmt.Sprintf("Hello %s!", message), nil
}

Регистрация и запуск воркера

w := worker.New(c, TaskQueue, worker.Options{})
w.RegisterWorkflow(SampleWorkflow)
w.RegisterActivity(SampleActivity)

err = w.Start()
if err != nil {
    log.Fatal(err)
}

Запуск выполнения рабочего процесса

we, err := c.ExecuteWorkflow(context.Background(), client.StartWorkflowOptions{
    ID:        "sample-workflow-id",
    TaskQueue: TaskQueue,
}, SampleWorkflow, "Developer")

Развертывание Temporal и воркеров Go

Варианты развертывания в production

  • Самостоятельно размещенный кластер Temporal: настройка служб Temporal (frontend, history, matching) с постоянным хранилищем (Cassandra, MySQL).
  • Temporal Cloud: управляемая служба Temporal с SLA и масштабированием.
  • Docker Compose или Kubernetes: для сред staging или production.

Убедитесь, что настроены:

  • Слой персистентности
  • Настройка пространства имен (namespace)
  • TLS/безопасная аутентификация (API-ключи, mTLS)

Масштабируемость воркеров

Разверните несколько воркеров за балансировщиком нагрузки. Воркеры масштабируются горизонтально, присоединяясь к тем же очередям задач и разделяя нагрузку.


Тестирование рабочих процессов и активностей в Go

Temporal включает набор инструментов для тестирования:

testSuite := testsuite.WorkflowTestSuite{}
env := testSuite.NewTestWorkflowEnvironment()

env.RegisterWorkflow(SampleWorkflow)
env.RegisterActivity(SampleActivity)

env.ExecuteWorkflow(SampleWorkflow, "Tester")

Проверка результатов:

var result string
require.NoError(t, workflowRun.Get(context.Background(), &result))
require.Equal(t, "Hello Tester!", result)

Тестирование с помощью наборов тестов обеспечивает детерминизм и надежность кода рабочих процессов перед развертыванием. Для Go-сервисов, лежащих в основе активностей Temporal — особенно тех, которые имеют циклы повторных попыток, дедлайны контекста и логику, управляемую таймерами, — Тестирование конкурентного кода Go с testing/synctest описывает, как проводить модульное тестирование этого зависящего от времени поведения в изоляции с помощью фиктивных часов и изолированных пузырей.


Лучшие практики для production

  • Таймауты и политики повторных попыток: Определите разумные таймауты и повторные попытки для активностей и рабочих процессов.
  • Структурированное логирование: Выводите логи с идентификаторами трассировки (trace IDs) и метаданными корреляции.
  • ID рабочих процессов: Используйте осмысленные ID рабочих процессов для отслеживаемости.
  • Дочерние рабочие процессы и ContinueAsNew: Разбивайте сложную логику на модульные выполнения, чтобы уменьшить размер истории.
  • Метрики и мониторинг: Интегрируйте с Prometheus или другими инструментами наблюдаемости.
  • Надежная публикация событий из активностей: Когда активность записывает данные в базу данных и также должна уведомить другую службу, используйте паттерн транзакционного ящика для исходящих сообщений для гарантии того, что событие не потеряется между коммитом в базу данных и публикацией в брокер.

Устранение распространенных проблем

Воркер не опрашивает очередь

  • Убедитесь, что указано правильное имя очереди задач.
  • Проверьте сетевое подключение к серверу Temporal.

Рабочий процесс не запускается

  • Проверьте регистрацию рабочего процесса перед запуском воркера.
  • Убедитесь в правильности параметров подключения клиента.

Сбои активностей

  • Проверьте конфигурацию политики повторных попыток.
  • Изучите веб-интерфейс для получения трассировок стека ошибок.

Ошибки недетерминированных рабочих процессов

Temporal обеспечивает детерминированное выполнение рабочих процессов. Проверьте код на наличие:

  • Использования math/rand
  • Горутин внутри логики рабочего процесса
  • Вызовов внешних систем внутри рабочих процессов

Всегда убедитесь, что рабочие процессы являются чистой логикой оркестрации, вызывая внешние системы через активности.


Реализация приложений для управления бизнес-процессами с Temporal в Go позволяет вам создавать бизнес-логику с состоянием, устойчивую и масштабируемую, используя знакомые идиомы Go. Благодаря гарантированной модели выполнения Temporal, встроенным повторным попыткам, очередям задач и поддержке наблюдаемости, вы можете сосредоточиться на основной логике вашего приложения, не изобретая оркестрацию заново. Начните с простых рабочих процессов и активностей, и масштабируйтесь к сложной распределенной оркестрации с уверенностью.


Полезные ссылки

Подписаться

Получайте новые материалы про системы, инфраструктуру и AI engineering.