赞
踩
您是否曾经开发过需要响应多个异步事件、与不可靠的外部资源通信或跟踪非常复杂事物状态的应用程序?
如果是这样,您可能熟悉无状态服务、数据库、cron作业和排队系统的混合,这是构建此类应用程序的现代方法。
然而,这些类型的系统通常会带来一些问题。维护每个单独组件的运行状况可能非常困难。此外,通常需要在基础设施上进行大量投资,以可视化整个系统的运行状况、定义超时和协调重试。扩展和维护这些系统是一项具有挑战性且成本高昂的工作。
编程框架(Temporal SDK)+ 后端服务(Temporal Server)的分布式系统
在业务模块当中按规则编写Workflow流程以及其具体的Activity, 注册到worker当中, 启动worker 外部⽤户触发Workflow, Temporal编排workflow形成⼀系列的task送到队列中, worker去队列取 任务, 执⾏后将结果返回给Temporal
举一个银行的流程示例:
使用Go SDK客户端从Go流程启动工作流,如下所述。
从已运行的工作流(称为子工作流)启动工作流。
注:启动工作流与执行工作流不同。启动工作流意味着您正在通知服务器开始跟踪工作流执行的状态。在临时应用程序中,您不直接运行工作流代码,而是由工作人员托管和执行工作流代码。
支持同步或异步启动工作流
启动工作流时不需要重试策略。如果未提供,则会为工作流生成默认值。但是,如果提供了,唯一需要的选项是初始间隔 Initial interval
详细见 Activity and Workflow Retries
|
工作流由其命名空间、工作流ID和运行ID唯一标识。
子工作流执行是从另一个工作流中派生的工作流执行。
工作流执行既可以是父工作流执行,也可以是子工作流执行,因为任何工作流都可以生成另一个工作流。
可以为每个子级设置策略,这意味着您可以在每个子级的基础上选择不传播终止/取消
活动SimpleActivity首先在任务队列sampleTaskQueue上的工作流工作进程内调用,会将options参数发送到TemporalServer
|
收到第一步的命令后,TemporalServer将活动任务添加到*Queue活动任务队列
轮询Queue活动任务队列的活动任务并开始执行
一旦活动执行成功完成,活动工作人员将向临时服务器发送CompleteActivityTask消息(以及活动执行的结果),临时服务器现在将控制权交还给工作流工作人员,以继续执行下一行代码并重复该过程
内容:从活动任务队列(启动状态)中提取了活动任务后何时会崩溃
影响:没有配置的话,Temporal将永远不会主动超时此活动执行以启动重试。活动执行变得“停滞”,最终用户将在没有反馈的情况下体验其工作流执行的无限期延迟。
配置后,Temporal在内部注册ActivityTaskTimedOut事件,该事件触发服务器根据活动执行的RetryPolicy尝试重试:
服务器再次将活动任务添加到活动任务队列中
服务器在工作流执行的可变状态下增加尝试次数
活动事件将可再次拾取活动任务
需要将其设置为比最大可能活动执行时间更长的时间。比如活动执行可能需要5分钟到5小时的时间,则需要将“开始关闭”设置为5小时以上
内容:显示的设置活动事件在任务队列中的时间(不建议),默认无穷大
影响:检查单个worker是否崩溃、轮询任务队列的工作组是否无法跟上活动任务的速率,还可以看到该队列中各部分的调度时间,从而报警,便于优化
注意:不会超时重试(重试会将活动任务放回同一任务队列)
如果给定的任务队列未按预期速率排空,则当您有将活动任务重新路由到其他任务队列的具体计划时,基于此超时执行其他补偿逻辑。
内容:用于控制活动执行所允许的总最大时间量,包括所有重试。(RetryPolicy.MaximumAttempts>1)
注意:虽然可以在RetryPolicy中控制重试间隔和最大重试次数,但关闭超时计划是基于所用总时间控制重试的最佳方法。我们建议使用Schedule-To-Close Timeout来限制重试次数,而不是调整最大尝试次数,因为在大多数情况下,这更符合所需的用户体验。
内容:用于检测两个活动任务间的最长时间,能够更快的重试活动
建议:对于长时间运行的活动,建议指定一个相对较短的心跳超时和持续的心跳
1、可执行工作流和/或活动代码。(可以独立托管其中一个)
2、worker轮询任务队列里的任务,以响应任务,然后将结果回传到临时服务器
3、只负责编排状态转换并将消息分派给下一个可用的工作进程
4、RegisterWorkflow和RegisterActivity调用实质上是在工作进程内创建完全限定函数名与其实现之间的内存映射。
ps:
1、任何给定的工作者都知道下一步执行哪段代码。
2、它是任务的“先进先出”队列,其中任务是执行改变工作流“状态”的代码块所需的上下文。
3、任务队列由Temporal Server维护。服务器将任务放入任务队列中,以安排、启动、取消和完成工作流和/或活动的某些部分。
4、任务队列在代码中以名称表示为字符串。
5、不需要显式注册,而是根据需要创建的。任务队列非常轻量级,系统可以处理的任务队列总数没有限制。
6、使用任务队列将任务交付给工作者,而不是通过同步RPC调用操作,有多个优点。
1、信号是一种完全异步且持久的机制,用于将数据发送到正在运行的工作流中(而不是在启动工作流或轮询活动中的外部数据时将数据作为参数传递)。
2、工作流可以使用SignalExternalWorkflow向其他工作流发送信号。
ps:
1、查询堆栈
|
2、查询工作流当前状态
|
3、一致性查询:最终一致性、强一致性
|
|
类似Go的select,允许goroutine等待多个通信。一个select块直到它的一个case可以运行,然后执行。如果多个已准备就绪,则随机选择一个。但是,由于随机性,正常的Go select语句不能直接在工作流内部使用。不同的是Temporal的Go SDK选择器可阻止channel的发送和接收,但可以监听未来推迟的工作。
|
可多次调用Select,只会为每个Selector选择器实例匹配一次。如果有多个项目可用,则不定义匹配顺序
在计时器和挂起的活动之间建立竞争
例如,计时器示例显示如何编写长时间运行的订单处理操作,其中:如果处理时间过长,我们会向用户发送一封关于延迟的通知电子邮件,但我们不会取消操作。如果操作在计时器触发之前完成,那么我们要取消计时器。
|
|
匹配消息不会消费,只有在c.Receive后才会消费message
可以使用selector.HasPending确保信号不会丢失
用法参考:Go SDK Selectors | Temporal Documentation
两种方式可启动定时工作流
|
注意点:
重试策略:如果工作流执行失败,并且向StartWorkflowOptions提供了RetryPolicy,则将根据RetryPolicy重试工作流执行。当工作流执行正在重试时,服务器将不会计划下一个工作流执行
取消工作流:终止或取消工作流执行也将停止Cron调度。Cron工作流在终止或取消之前不会停止
|
ps:第一天成功了,第二天失败了,第三天还会获得第一天成功的结果
通过在客户端实例化期间在ClientOptions中提供opentracing.Tracer实现来配置跟踪
Temporal支持传播自定义的上下文(类似go的ctx)
workflow
Workflows in Go | Temporal Documentation
超时
The 4 Types of Activity timeouts | Temporal Documentation
https://docs.temporal.io/docs/content/how-to-set-activityoptions-in-go/#scheduletostarttimeout
docker安装 Install Docker Engine on CentOS | Docker Documentation
What is tctl? | Temporal Documentation
docker-compose/README.md at main · temporalio/docker-compose · GitHub
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。