关键概念
Workflow:Workflow是在编排层的关键概念,每种类型是注册到服务端的一个WorkflowType,每个WorkflowType可以创建任意多的运行实例,即WorkflowExecution,每个Execution有唯一的WorkflowID,如果是Cron/Continue-as-New, 每次执行还会有唯一的RunID。Workflow可以有环,可以嵌套子工作流(ChildWorkflow);
Activity:Workflow所编排的对象主要就是Activity,编排Activity就像正常写代码一样,只要具备确定性即可;
Signal:对于正在运行的WorkflowExecution,可以发送携带参数的信号,Workflow中可以等待或根据条件处理信号,动态控制工作流的执行逻辑。
任何 workflow 引擎(包括那些使用类似于 Temporal 的 Worflow-as-Code、或使用 YAML/JSON/XML 的引擎)都是有状态机的。需要一个状态机来定义运行任务的顺序,并且反应外部事件。
每个实用的工作流引擎都使用队列将任务派发给工作进程(托管那些任务的工作进程)
工作流
下面来看下子工作流的作用:
子工作流程可以由不包含父工作流程代码的一组单独的worker托管。因此,它可以作为单独的服务,被多个其他工作流程调用。
单个工作流程的大小是有限的。例如,它无法执行 100k 活动。子工作流程可用于将问题划分为更小的块。
子工作流可用于使用其 ID 来管理资源以保证唯一性。例如,管理主机升级的工作流可以为每个主机拥有一个子工作流(主机名是工作流 ID),并使用它们来确保主机上的所有操作都被序列化。
子工作流可用于执行一些周期性逻辑,而不会增加父历史记录的大小。父级启动一个子级,该子级执行周期性逻辑。从父级的角度来看,它只是一个子工作流调用。
与将所有应用程序逻辑并置在单个工作流中相比,子工作流的主要限制是缺乏共享状态。父级和子级只能通过异步信号进行通信。但是,如果它们之间存在紧密耦合,那么使用单个工作流程并仅依赖于共享对象状态可能会更简单。
工作流不仅仅可以是函数,还可以在其中使用 OO 的全部功能。使用结构、接口和其他面向对象技术将逻辑分解为更易于管理的抽象。
任务重放
当我们的任务因为某些原因被shutdown之后,在重启之后,temporal将根据事件历史记录来replay,以便工作流程状态带到发生故障的确切位置,并可以继续执行。
例如,如果有一个仅添加 10 个数字的 for 循环,此时服务在 for 循环期间崩溃,那么在replay期间,该 for 循环将从头开始执行。
如果有一个 for 循环,在循环中执行调用activity、workflow.sleep 等写入工作流事件历史记录的操作,那么在循环中发生崩溃恢复后,它将从它之前停止的确切位置开始执行。
确定性代码
下面看一个不是确切代码的列子:
例如,工作流的原始执行可以执行活动 A。但在replay期间,它可能会执行与执行历史记录不匹配的活动 B。
if (random() > 0.5) {
ExecuteActivity("A");
} else {
ExecuteActivity("B");
}
activity结果记录在工作流执行历史记录中。因此,在恢复期间,结果是从历史记录中获取的,而不执行activity。
因此,我们要避免上面的类似代码:不能在workflow或者activity中有不确定性的代码逻辑。
http://timd.cn/temporal/application-development-foundations/
https://yangmingblog.cn/2022/03/19/temporal-yi-qiang-da-de-fen-bu-shi-gong-zuo-liu-yin-qing/#toc-heading-2