3. Temporal 开发环境搭建:Server、CLI 与 SDK 配置

搭建可靠的 Temporal 开发环境是进行工作流开发的第一步。本章将指导你完成 Temporal Server 的安装与启动、Temporal CLI 的常用操作,以及 Go 和 Java SDK 的工程配置。完成本环境搭建后,你将拥有一个可本地运行的工作流调试平台。

3.1 Temporal Server 安装

Temporal Server 支持多种部署方式:本地开发推荐使用 Docker Compose,生产环境建议使用 Kubernetes 或 Temporal Cloud。以下为本地开发环境的快速安装步骤。

3.1.1 使用 Docker Compose 一键启动

Temporal 官方提供了 docker-compose.yml 文件,包含 Server、Web UI 和 Cassandra/PostgreSQL 等依赖组件。

# 1. 克隆官方仓库
git clone https://github.com/temporalio/docker-compose.git
cd docker-compose

# 2. 启动所有服务(默认使用 Cassandra)
docker compose up -d

# 3. 验证服务状态
docker compose ps

启动成功后,你将获得以下核心服务端口:

组件 默认端口 说明
Temporal Server (gRPC) 7233 Worker 与 Client 连接端口
Temporal Web UI 8080 浏览器访问工作流状态
Cassandra 9042 默认持久化存储
提示: 若需切换为 PostgreSQL 或 MySQL,可在 docker-compose.yml 同级目录下使用 docker compose -f docker-compose-postgres.yml up -d 启动。

3.1.2 验证 Server 运行状态

打开浏览器访问 http://localhost:8080,你将看到 Temporal Web UI 的命名空间列表页面。默认存在 default 命名空间,表示 Server 已正常运行。

架构说明: Temporal Server 由 Frontend、History、Matching、Worker 四个核心服务组成。Frontend 负责接收客户端请求,History 维护工作流状态,Matching 管理任务队列,Worker 执行实际任务。下图展示了本地开发环境的组件关系。
Temporal 本地开发环境架构 开发机 Go Worker SDK: v1.20+ Java Worker SDK: v1.20+ CLI 客户端 temporal CLI Web 浏览器 localhost:8080 Docker 容器网络 Temporal Server (7233) Web UI (8080) Cassandra / PostgreSQL Elasticsearch (可选) Temporal Cloud 生产命名空间 xxx.tmprl.cloud 高可用存储 托管服务 本地开发使用 Docker 网络,生产环境建议使用 Temporal Cloud

3.2 Temporal CLI 使用

Temporal CLI 是官方提供的命令行工具,用于管理工作流、任务队列、命名空间等资源。安装方式如下:

# macOS (Homebrew)
brew install temporal

# Linux (curl 安装)
curl -sSf https://temporal.download/cli.sh | sh

# Windows (Scoop)
scoop bucket add temporal https://github.com/temporalio/scoop-temporal.git
scoop install temporal

3.2.1 核心命令速查

命令 功能 示例
temporal server start-dev 启动本地开发 Server(无需 Docker) temporal server start-dev --db-filename temporal.db
temporal workflow list 列出命名空间下的工作流 temporal workflow list --namespace default
temporal workflow describe 查看工作流详情 temporal workflow describe --workflow-id xxx
temporal workflow terminate 终止运行中的工作流 temporal workflow terminate --workflow-id xxx --reason "test"
temporal task-queue list 查看任务队列 temporal task-queue list --namespace default
注意: temporal server start-dev 命令会启动一个单节点 Server,使用 SQLite 作为存储,适合快速原型验证。生产环境请勿使用此模式。

3.2.2 常用操作示例

以下命令演示了如何通过 CLI 与运行中的 Temporal Server 交互:

# 1. 注册命名空间
temporal namespace register --namespace my-workflow-ns

# 2. 查看命名空间详情
temporal namespace describe --namespace my-workflow-ns

# 3. 启动一个工作流(假设 Worker 已运行)
temporal workflow start \
  --task-queue hello-world-queue \
  --workflow-id my-first-workflow \
  --type GreetWorkflow \
  --input '"Temporal"' \
  --namespace my-workflow-ns

# 4. 查看工作流执行结果
temporal workflow show --workflow-id my-first-workflow --namespace my-workflow-ns

3.3 Go SDK 配置

Go SDK 是 Temporal 官方支持最成熟的客户端之一。以下步骤演示如何在一个 Go 项目中集成 Temporal SDK。

3.3.1 初始化 Go 模块并安装 SDK

# 创建项目目录
mkdir temporal-go-demo && cd temporal-go-demo
go mod init temporal-go-demo

# 安装 Temporal Go SDK
go get go.temporal.io/sdk@v1.26.0

3.3.2 编写 Worker 与 Client 代码

以下是一个最小化的 Worker 启动代码,连接到本地 Server 并监听任务队列:

package main

import (
    "log"
    "go.temporal.io/sdk/client"
    "go.temporal.io/sdk/worker"
)

func main() {
    // 1. 创建 Temporal Client
    c, err := client.Dial(client.Options{
        HostPort:  "localhost:7233",
        Namespace: "default",
    })
    if err != nil {
        log.Fatalln("无法创建 Temporal Client", err)
    }
    defer c.Close()

    // 2. 创建 Worker
    w := worker.New(c, "hello-world-queue", worker.Options{})

    // 3. 注册工作流与活动
    w.RegisterWorkflow(GreetWorkflow)
    w.RegisterActivity(GreetActivity)

    // 4. 启动 Worker(阻塞)
    err = w.Run(worker.InterruptCh())
    if err != nil {
        log.Fatalln("Worker 运行失败", err)
    }
}
最佳实践: 在 client.Dial 中建议设置 Logger 和 MetricsHandler,便于生产环境监控。SDK 默认使用 log.Printf 输出日志。

3.4 Java SDK 配置

Java SDK 适用于 Spring Boot 或纯 Java 项目。以下以 Maven 项目为例进行配置。

3.4.1 Maven 依赖配置

在 pom.xml 中添加 Temporal SDK 依赖:

<dependency>
    <groupId>io.temporal</groupId>
    <artifactId>temporal-sdk</artifactId>
    <version>1.22.0</version>
</dependency>

3.4.2 编写 Worker 启动类

import io.temporal.client.WorkflowClient;
import io.temporal.serviceclient.WorkflowServiceStubs;
import io.temporal.worker.Worker;
import io.temporal.worker.WorkerFactory;

public class TemporalWorker {
    public static void main(String[] args) {
        // 1. 创建 gRPC 连接
        WorkflowServiceStubs service = WorkflowServiceStubs
            .newInstance(WorkflowServiceStubsOptions.newBuilder()
                .setTarget("localhost:7233")
                .build());

        // 2. 创建 WorkflowClient
        WorkflowClient client = WorkflowClient.newInstance(service,
            WorkflowClientOptions.newBuilder()
                .setNamespace("default")
                .build());

        // 3. 创建 WorkerFactory 并启动 Worker
        WorkerFactory factory = WorkerFactory.newInstance(client);
        Worker worker = factory.newWorker("hello-world-queue");
        worker.registerWorkflowImplementationTypes(GreetWorkflowImpl.class);
        worker.registerActivitiesImplementations(new GreetActivityImpl());

        factory.start();
        System.out.println("Worker 已启动,等待任务...");
    }
}

3.5 环境验证清单

完成上述配置后,请按以下清单验证环境是否就绪:

  • Server 状态: curl -s http://localhost:7233/health 返回 {"status":"SERVING"}
  • Web UI 可访问: 浏览器打开 http://localhost:8080 显示命名空间列表
  • CLI 连通性: temporal workflow list --namespace default 不报错
  • Go Worker 启动: 运行 Worker 程序后,控制台无连接错误
  • Java Worker 启动: 运行 Worker 程序后,输出 "Worker 已启动" 日志
常见问题排查:
  • 若 Worker 连接失败,检查 HostPort 是否与 Server 端口一致(默认 7233)。
  • 若 Web UI 无法访问,确认 Docker 容器中 temporal-web 服务是否正常运行。
  • 若 CLI 命令超时,尝试设置环境变量 TEMPORAL_CLI_ADDRESS=localhost:7233。
SDK 与 Server 交互流程 Go / Java SDK Client + Worker Temporal Server gRPC 7233 持久化存储 Cassandra/PostgreSQL 交互步骤 1. SDK Client 通过 gRPC 向 Server 发起 StartWorkflow / Signal / Query 请求 2. Server 将工作流事件持久化到存储层,并调度任务到任务队列 3. SDK Worker 轮询任务队列,拉取任务并执行 Activity,结果回写 Server

3.6 本章小结

通过本章的学习,你已完成 Temporal 开发环境的全链路搭建:

  • 使用 Docker Compose 启动了包含 Server、Web UI 和存储的完整环境
  • 掌握了 Temporal CLI 的安装与核心命令
  • 配置了 Go SDK 和 Java SDK,并编写了最小 Worker 启动代码
  • 理解了 SDK 与 Server 之间的 gRPC 交互流程