4. Temporal 平台概述:Temporal 是什么、核心组件与工作流活动
Temporal 是一个开源的、分布式、可扩展的工作流编排引擎,专门用于构建高可靠、长时间运行的异步应用程序。它源自 Uber 内部解决微服务编排难题的工程实践,后于 2019 年开源并独立运营。Temporal 的核心价值在于将复杂的业务逻辑(工作流)与具体的执行细节(活动)解耦,让开发者能够以编写普通代码的方式,构建具有自动重试、超时管理、状态持久化和故障恢复能力的分布式系统。
核心思想:Temporal 不是消息队列,也不是简单的定时任务框架。它是一个“容错的状态机”,确保你的工作流代码无论经历多少次进程崩溃、机器宕机或网络分区,都能从最后一个稳定状态继续执行,且不会丢失任何执行痕迹。
4.1 Temporal 的核心组件
Temporal 平台由三个核心角色构成:Server、Worker 和 Client。它们各司其职,通过 gRPC 协议通信,共同完成工作流的调度与执行。
| 组件 | 职责 | 部署形态 | 关键特性 |
|---|---|---|---|
| Server | 工作流编排中枢,负责状态持久化、任务分发、时钟管理 | 独立集群(通常 3-5 节点) | 基于 Cassandra/PostgreSQL/MySQL 存储事件历史;无单点故障 |
| Worker | 执行工作流与活动的业务进程 | 嵌入在应用服务中,或独立部署 | 轮询 Task Queue;可水平扩展;支持多语言 SDK |
| Client | 触发工作流、查询状态、发送信号的入口 | SDK 客户端库 | 提供同步/异步 API;支持 OpenAPI 网关集成 |
4.2 工作流(Workflow)
工作流是 Temporal 中的核心编排单元,它定义了一组业务步骤的执行顺序、分支、循环、超时和错误处理策略。工作流代码运行在 Worker 进程中,但它的执行状态完全由 Server 持久化。
- 确定性(Deterministic):工作流代码必须是确定性的——相同的输入必须产生相同的执行路径。这意味着不能直接使用随机数、系统时间、网络 I/O 等非确定性操作。这些操作应封装在活动中。
- 事件溯源(Event Sourcing):Server 将工作流的每个决策(Decision)和任务结果(Activity Task)以事件的形式追加存储。当 Worker 重启或故障转移时,Server 会重放事件历史,重建工作流状态。
- 长时间运行:工作流可以运行数秒、数天甚至数年。Temporal 通过“异步等待”机制(如
Workflow.sleep或await)在不占用 Worker 线程的情况下挂起工作流,直到外部信号或时间触发。
最佳实践:将工作流视为“编排者”,只负责决策和流程控制,不执行实际业务逻辑。所有可能失败、耗时或非确定性的操作都委托给活动。
4.3 活动(Activity)
活动是 Temporal 中的实际业务执行单元。它执行具体的任务,例如调用第三方 API、读写数据库、发送邮件、处理文件等。活动可以同步或异步执行,并支持自动重试和心跳检测。
| 特性 | 工作流(Workflow) | 活动(Activity) |
|---|---|---|
| 执行内容 | 编排逻辑、条件判断、循环 | 实际业务操作(I/O、计算) |
| 确定性要求 | 必须确定性 | 无限制(可包含随机、时间、网络) |
| 重试策略 | 由活动重试策略决定 | 可配置重试次数、间隔、退避 |
| 超时控制 | 工作流执行超时 | 活动调度超时、执行超时、心跳超时 |
| 状态持久化 | 完整事件历史 | 仅记录输入/输出及心跳 |
| 典型用途 | 订单流程、审批链、数据管道 | 支付扣款、发送通知、文件转换 |
4.4 工作流与活动的协作模式
在实际应用中,工作流通过 Task Queue 将活动任务分发给 Worker。Worker 从队列中拉取任务并执行,执行结果通过 gRPC 返回给 Server,Server 再将结果写入事件历史并推进工作流状态。
- Client 调用
StartWorkflow向 Server 发起工作流执行请求。 - Server 创建工作流实例,持久化初始事件,并将第一个决策任务放入 Task Queue。
- Worker 轮询到决策任务,执行工作流代码。当工作流代码调用
executeActivity时,Worker 向 Server 请求调度活动。 - Server 将活动任务放入对应的 Activity Task Queue。
- Worker(可以是同一进程或不同进程)拉取活动任务并执行实际业务逻辑。
- 活动完成后,Worker 将结果报告给 Server,Server 更新事件历史并继续推进工作流。
注意:工作流代码中的
await 或 sleep 不会阻塞 Worker 线程。Temporal 会将这些“等待点”记录为事件,Worker 可以立即处理其他工作流实例。这是 Temporal 实现高并发和资源高效利用的关键机制。