Go에서 Temporal을 사용하여 워크플로우 애플리케이션을 구현하는 완전한 가이드
Go로 Temporal SDK를 사용하여 워크플로우를 작성하세요.
Temporal은 개발자가 익숙한 프로그래밍 언어인 Go를 사용하여 내구성 있고 확장성이 높고 오류에 강한 워크플로우 애플리케이션을 구축할 수 있도록 하는 오픈소스, 기업용 등급의 워크플로우 엔진입니다.
복잡한 상태 전환과 재시도가 필요한 분산 애플리케이션은 신뢰할 수 있는 오케스트레이션 프레임워크가 필요합니다.
이 가이드는 Go에서 Temporal을 사용한 워크플로우 애플리케이션의 구현 방법을 설명합니다. 구성, 샘플 코드, 배포 전략, 최고 실천 사례, 문제 해결 방법에 대해 다룹니다.

Temporal이란 무엇이며 Go와 함께 사용하는 이유
Temporal은 오류에 강하고 오랜 시간 동안 실행되는 분산 애플리케이션을 구축하기 위해 설계된 워크플로우 오케스트레이션 프레임워크입니다. Temporal은 상태 관리, 재시도, 타이머, 오류 복구 등을 뒤에서 처리하여 개발자가 복잡한 오케스트레이션 코드 없이 애플리케이션 논리에 집중할 수 있도록 합니다. Temporal Go SDK를 통해 Go를 포함한 여러 언어를 지원합니다.
Go와 함께 Temporal을 사용하면 다음과 같은 이점을 얻을 수 있습니다:
- 워크플로우는 내구성 있고 재생 가능한 상태를 유지합니다.
- 활동의 재시도 및 타임아웃은 자동으로 처리됩니다.
- 시스템 상태는 오류가 발생하더라도 지속됩니다.
- 작업 오케스트레이션 논리는 고유한 Go 스타일의 코드에서 실행됩니다.
핵심 개념: 워크플로우, 활동, 워커
첫 번째 Temporal Go 애플리케이션을 구축하기 전에 다음 주요 개념을 이해해야 합니다:
워크플로우
워크플로우는 활동을 호출하는 내구성 있는 조정 논리입니다. 이는 결정적이어야 하며, Temporal 엔진은 이를 신뢰할 수 있게 재생할 수 있습니다. Go에서는 특별한 workflow.Context 매개변수를 가진 일반적인 Go 함수로 워크플로우를 작성합니다.
활동
활동은 I/O, 외부 API 호출과 같은 비결정적인 작업을 포함하는 작업 단위입니다. 활동은 워크플로우 외부에서 실행되며 결과를 워크플로우 논리로 다시 전달합니다.
워커
워커는 워크플로우 및 활동 함수를 호스팅하고 실행합니다. 워커는 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 서버와 웹 UI를 시작합니다.
설정: 클라이언트 및 작업 대기열
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 클러스터: Cassandra, MySQL과 같은 지속 가능한 저장소와 함께 Temporal 서비스(프론트엔드, 히스토리, 매칭)를 설정합니다.
- Temporal 클라우드: SLA와 확장성을 제공하는 관리형 Temporal 서비스.
- 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)
테스트 스위트를 사용하여 워크플로우 코드의 결정성과 신뢰성을 배포 전에 확인할 수 있습니다.
프로덕션 최고 실천 사례
- 타임아웃 및 재시도 정책: 활동 및 워크플로우에 적절한 타임아웃과 재시도를 정의합니다.
- 구조화된 로깅: 추적 ID와 상관 메타데이터를 포함한 로그를 생성합니다.
- 워크플로우 ID: 추적성을 위해 의미 있는 워크플로우 ID를 사용합니다.
- 자식 워크플로우 및 ContinueAsNew: 복잡한 논리를 모듈형 실행으로 분할하여 역사 기록 크기를 줄입니다.
- 메트릭 및 모니터링: Prometheus나 다른 관찰 도구와 통합합니다.
일반적인 문제 해결
워커가 대기열을 수신하지 않음
- 올바른 작업 대기열 이름을 확인하세요.
- Temporal 서버와의 네트워크 연결을 확인하세요.
워크플로우가 시작되지 않음
- 워커 시작 전 워크플로우 등록을 확인하세요.
- 클라이언트 연결 파라미터를 확인하세요.
활동 실패
- 재시도 정책 구성 확인.
- 웹 UI에서 오류 스택 트레이스를 확인하세요.
비결정적인 워크플로우 오류
Temporal은 결정적인 워크플로우 실행을 강제합니다. 코드를 검토할 때 다음을 확인하세요:
math/rand사용- 워크플로우 논리 내부의 goroutine
- 워크플로우 내부의 외부 시스템 호출
워크플로우는 외부 시스템을 활동을 통해 호출하는 순수한 오케스트레이션 코드여야 합니다.
Temporal in Go을 사용하여 워크플로우 애플리케이션을 구현하면 익숙한 Go 스타일로 상태가 있는, 견고하고 확장성이 높은 비즈니스 논리를 구축할 수 있습니다. Temporal의 보장된 실행 모델, 내장된 재시도, 작업 대기열, 관찰 지원을 통해 오케스트레이션을 다시 만들 필요 없이 핵심 애플리케이션 논리에 집중할 수 있습니다. 간단한 워크플로우와 활동부터 시작하여 복잡한 분산 오케스트레이션으로 확장하세요.