GoでTemporalを使用したワークフロー応用の実装: 完全ガイド

GoでTemporal SDKを使用してワークフローを構築する

目次

Temporal は、開発者がGoなどの馴染みのあるプログラミング言語を使って、耐障害性があり、拡張性があり、信頼性の高いワークフロー アプリケーションを構築できるオープンソースで、企業向けのワークフロー エンジンです。Go など。

複雑な状態遷移とリトライを必要とする分散アプリケーションは、信頼性の高いオーケストレーション フレームワークを必要とします。

本ガイドでは、Go での Temporal のワークフロー アプリケーションの実装方法について説明します。設定、サンプルコード、デプロイ戦略、ベストプラクティス、トラブルシューティングをカバーしています。

Go Workplace

Temporal とは、そしてなぜGoと併用するのか

Temporal は、障害に強い、長期間にわたる分散アプリケーションを構築するためのワークフロー オーケストレーション フレームワークです。Temporal は、状態管理、リトライ、タイマー、障害からの回復をバックグラウンドで処理し、開発者がオーケストレーションコードのための雛形を作成することなく、アプリケーションロジックに集中できるようにします。Temporal Go SDK を介してGoをサポートしています。

Temporal と Go を併用することで:

  • ワークフローは耐久性があり、再現可能です。
  • アクティビティのリトライとタイムアウトは自動的に処理されます。
  • システム状態は障害が発生しても保持されます。
  • タスクのオーケストレーションロジックは、Go のイディオムに従ったコードで記述されます。

核心概念:ワークフロー、アクティビティ、ワーカー

最初の Temporal Go アプリケーションを構築する前に、以下の重要な概念を理解してください:

ワークフロー

ワークフロー は、アクティビティを呼び出す耐久性のある調整ロジックです。これは決定論的である必要があります - Temporal エンジンは、信頼性よく再現できます。Go では、特別な workflow.Context パラメータを持つ通常の Go 関数としてワークフローを記述します。

アクティビティ

アクティビティ は、非決定論的な操作(I/O、外部 API 呼び出し)を含む作業の単位です。アクティビティはワークフローの外で実行され、結果をワークフロー ロジックに戻します。

ワーカー

ワーカー は、ワークフローおよびアクティビティ関数をホストおよび実行します。ワーカーは、Temporal サーバーのタスクキューからタスクをポーリングし、タスクを処理します。ワーカーを開始する前に、ワークフローおよびアクティビティを登録する必要があります。

タスクキュー

タスクキュー は、ワーカーが Temporal サーバーからタスクを受け取る方法です。ワークフローおよびアクティビティは、使用するタスクキュー名を指定します。


Temporal と Go プロジェクトのセットアップ

事前準備

  • 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 サーバーと Web 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 Cloud: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 サーバーへのネットワーク接続を確認してください。

ワークフローが開始できない

  • ワーカーの開始前にワークフロー登録を確認してください。
  • クライアント接続パラメータを確認してください。

アクティビティの失敗

  • リトライポリシーの設定を確認してください。
  • Web UI でエラースタックトレースを確認してください。

非決定論的なワークフローのエラー

Temporal は決定論的なワークフロー実行を強制します。コードを確認してください:

  • math/rand の使用
  • ワークフロー論理内のゴルーチン
  • ワークフロー内の外部システム呼び出し

ワークフローは常に 純粋なオーケストレーションコード であり、アクティビティを通じて外部システムを呼び出すようにしてください。


Temporal in Go を使用してワークフロー アプリケーションを実装することで、馴染みのある Go のイディオムを使って、状態を保持し、信頼性があり、拡張性のあるビジネスロジックを構築できます。Temporal の保証された実行モデル、組み込みのリトライ、タスクキュー、観測性サポートにより、オーケストレーションを再考することなく、コアアプリケーションロジックに集中できます。単純なワークフローとアクティビティから始めて、複雑な分散オーケストレーションにスケールする自信を持ってください。


有用なリンク