Schedule 包含用于在特定时间启动工作流执行(Workflow Execution)的指令。Schedule 提供比 Temporal Cron Job 更灵活和用户友好的方法。
Schedule 拥有 ID,独立于工作流执行(Workflow Execution)。这与 Temporal Cron Job 不同,它依赖 cron 调度作为工作流执行的一个属性。
Schedule 的操作(Action)由工作流执行(Workflow Execution)属性确定,比如工作流类型(Workflow Type)、任务队列(Task Queue)、参数及超时。
Schedule 启动的工作流执行拥有如下附加属性:
TemporalScheduledStartTime
搜索属性(Search Attribute)被添加到工作流执行。其值是操作的时间戳TemporalScheduledById
搜索属性被添加到工作流执行。其值是 Schedule IdSchedule 规格(Spec)描述执行操作的时间。存在两种 Schedule 规格:
取决于接口或使用的 SDK,这两种类型有多种表示形式,但它们都支持相同的特性。
在 tctl 中,以字符串形式指定间隔,比如 45m
表示每 45 分钟;6h/5h
表示每 6 个小时,但在每个时间段内的第 5 个小时开始。
在 tctl 中,可以用带五个(或六个、或七个)位置字段的传统 cron 表达式或带命名字段的 JSON 的形式指定日历表达式:
{
"year": "2022",
"month": "Jan,Apr,Jul,Oct",
"dayOfMonth": "1,15",
"hour": "11-14"
}
可用的日历 JSON 字段如下:
year
month
dayOfMonth
dayOfWeek
hour
minute
second
comment
每个字段可以包含逗号分隔的范围列表(或 *
通配符),每个范围可以包含一个斜线,后面跟着一个跳过值。hour
、minute
、second
字段默认为 0,其它字段默认为 *
,因此可以仅用几个字段描述许多有用的规格。
对于 month
,可以使用月份的名称代替整数(大小写不敏感,允许缩写)。对于 dayOfWeek
,可以使用星期几的名称。
comment
字段是可选的,可用于包含表示日历规格的意图的自由格式的描述。
无论你提供哪种形式,日历和间隔规格都被转换成规范化的表现形式。当你“描述”或“列出” Schedule 时,看到的可能与你输入的不完全一样,但是它们有相同的含义。
其它规格特性:
多个间隔/日历表达式:规格可以拥有多个间隔和/或日历表达式的组合,来定义特定的 Schedule
时间范围:为规格提供绝对的开始或结束时间(或两者),可以确保在开始时间之前或结束时间之后不执行任何操作
排除:规格可以包含 0 或多个日历表达式形式的排除。这可用于表达“除假日外的每周一中午”之类的调度。必须提供自己的排除集合,并在每个调度中包含它;没有预定义的集合。(tctl 或 Temporal Web UI 当前未暴露该特性)
抖动:如果提供,那么给每个操作时间添加介于零和最大抖动之间的随机偏移量
时区:默认情况下,用 UTC 时间解释基于日历的表达式。Temporal 推荐使用 UTC,避免各种令人惊讶的时区属性。如果不想使用 UTC,那么可以提供时区名称。从磁盘或嵌入到二进制文件中的 fallback 将时区定义加载到 Temporal Server Worker Service。
为获得更多操作控制,在 Schedule Spec 中嵌入时区数据库文件的内容。(注意:tctl 和 Temporal Web UI 当前未暴露该特性。)
可以暂停 Schedule。在暂停 Schedule 时,规格(Spec)不受影响。但是,仍然可以使用 tctl schedule trigger 命令强制执行手动操作。
为协助开发者和操作者之间的沟通,在暂停或重启时,可以更新“notes”字段,来存储当前状态的解释。
可以回填(Backfill)Schedule。当回填 Schedule 时,所有本应在特定时间段执行的操作都在现在执行(如果使用 AllowAll
Overlap Policy,那么并行执行;如果使用 BufferAll
,那么顺序执行)。可以使用它填充 Schedule 因现在已解决的外部条件而暂停的时间段或创建 Schedule 之前的时间段的运行(run)。
Schedule 可被限制到特定数量的计划操作(scheduled Actions)(也就是说,不立即触发)。在那之后,它像被暂停了一样。
Schedule 支持一组启用自定义行为的策略(Policy)。
重叠策略(Overlap Policy)控制当到达启动工作流执行(Workflow Execution)的时间,但之前启动的工作流执行仍在运行时如何处理。可用的选项如下:
Skip
:默认。不发生任何事情;不启动工作流执行BufferOne
:在当前的工作流执行完成后立即启动。缓冲被限制到 1。如果应该启动另一个工作流执行,但是缓冲中已经有一个,最终只有缓冲中的那个启动BufferAll
:允许缓冲不限数量的工作流。顺序地启动它们CancelOther
:取消正在运行的工作流执行,然后在旧的完成取消后,启动新的TerminateOther
:终止正在运行的工作流执行,立即启动新的AllowAll
:启动任意数量的并发工作流执行。使用这种策略时,Schedule 启动的多个工作流执行可以同时执行当 Schedule 应该执行操作时,Temporal 集群可能处于关闭或不可用状态。当集群重新启动时,弥补窗口(Catchup Window)控制此时应该执行哪些错过的操作(Action)。默认是 1 分钟,这意味着 Schedule 尝试执行不超过一分钟的操作。停机时间超过弥补窗口可能导致错过操作。(但是可以 Backfill。)
如果设置该策略,那么 Schedule 启动的工作流执行以失败或超时(但不是取消或终止)结束会导致 Schedule 自动地暂停。
注意:与 AllowAll
重叠策略一起使用时,暂停可能不会应用到下一个工作流执行,因为在失败的工作流执行完成之前,下一个工作流执行可能已经开始。它仅应用到失败的工作流执行完成后被调度启动的工作流执行。
Schedule 启动的工作流执行可以获取最近的成功的运行(run)的完成结果。(你如何做这件事依赖你使用的 SDK。)
对于不允许重叠的重叠策略,“最近的成功的运行”的定义很直接。对于 AllowAll
策略,它指代在讨论中的运行开始的时刻的最近完成的运行。细想下面的重叠运行:
time -------------------------------------------->
A |----------------------|
B |-------|
C |---------------|
D |--------------T
如果 D 在时刻 T 寻找最后完成结果,它获得 A 的结果。而不是 B,即便 B 的开始更近,因为 A 完成的更晚。也不是 C,即便 C 在 A 后面完成,因为在 D 开始时,而不是它查询时,捕获 D 的结果。
失败和超时不影响最后完成结果。
Schedule 启动的工作流(Workflow)可以获取它启动的时刻结束的、最近的运行(run)的失败细节。不像最后完成结果,成功的运行重置最后的失败。
试验性
Scheduled Workflow 特性在 Temporal Server 1.18 版本中可用。
在内部,Schedule 被实现为 Workflow。如果使用高级可视化(Advanced Visibility)(ElasticSearch),常规视图隐藏这些工作流执行(Workflow Execution)。如果使用标准可视化(Standard Visibility),它们是可见的,即便没有需要与它们直接地进行交互。
在语言 SDK 中对 Schedule 的原生支持即将到来。当前, tctl
和 web UI 是 Schedule 的主要接口。对于高级使用,也可以通过从 SDK 获取 WorkflowServiceClient
对象及调用诸如 CreateSchedule
之类的方法使用 gRPC API。