Реализация приложений Workflow с использованием Temporal на Go: Полное руководство

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

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

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

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

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

Go Workplace

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

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

Используя Temporal с Go:

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

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

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

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

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

Активности

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

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

Рабочий процесс размещает и выполняет функции Workflow и Activity. Рабочие процессы опрашивают очереди задач сервера Temporal и обрабатывают задачи. Они должны зарегистрировать рабочие процессы и активности перед запуском.

Очереди задач

Очередь задач — это способ, которым рабочий процесс получает задачи от сервера 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

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

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 рабочих процессов

Опции развёртывания в продакшене

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

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

  • Уровень сохранения данных
  • Настройка пространства имён
  • 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)

Тестирование с помощью наборов тестов обеспечивает детерминированность и надёжность кода рабочих процессов перед развёртыванием.


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

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

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

Рабочий процесс не опрашивает

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

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

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

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

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

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

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

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

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


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


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