蓝盟IT小贴士,来喽!
个人资料
netflix conductor是一个用JAVA语言编写的开源流程引擎,用于构建基于微服务的流程。 具有以下特性。
可以创建复杂的业务流程。 流程中的单个任务由一个微服务实现。
基于JSON DSL创建工作流以组织任务的执行。
工作流在运行时显示,并且可以钻取。
提供暂停、重新启动、重新启动等各种控制模型。
提供了充分利用微服务的简单方法。
具有扩展到百万个进程同时运行的服务能力。
通过队列服务将客户端和服务端分开。
支持通过HTTP或其他RPC协议传输数据
二基本概念
一个任务
Task是最小执行单元,包含发送HTTP请求等执行逻辑。
系统任务:由conductor服务执行,这些任务的执行与引擎在同一JVM中。
工作任务:由工作器服务运行,运行与引擎隔离,工作器通过队列获取任务后,向引擎运行和更新结果的状态。 Worker的实现是跨语言进行的,使用Http协议与服务器进行通信。
conductor中内置了几个系统任务:
功能性任务:
http :发送http请求
json_jq_TRANSFORM:jq命令执行,普通用户JSON的转换,具体可以看JQ官方文档
KAFKA_PUBLISH:发布了kafka消息
流程控制任务:
SWITCH (原诊断) :条件判断分支,类似于代码的switch case
FORK :启动并行分支以调度并行任务
JOIN :汇总并行分支,用于汇总并行任务
DO_WHILE :循环。 类似于代码中的do while
WAIT :在外部时间触发节点状态更新之前正在运行,可以用于等待外部操作
SUB_WORKFLOW :执行子进程、其他进程
TERMINATE指定终止进程,以便输出尽早终止进程。 可以与SWITCH节点配合使用,如代码中的预return语句
自定义任务:
对于System Task,Conductor提供了工作流系统任务抽象类,并允许定制扩展实现。
对于工作任务,可以实现conductor的客户端工作器接口实现执行逻辑。2工作流
工作流由应该执行的一系列任务构成,conductor使用json记述了任务流程的关系。
除了基本的顺序流程外,内置的SWITCH、FORK、JOIN、DO_WIHLE和TERMINATE任务还提供了分支、并行、循环和提前终止等流程控制。
3输入输出
Task的输入是作为工作流实例化的一部分或其他Task的输出的映射。 允许来自工作流或其他任务的输入/输出作为后续任务的输入。
Task有自己的输入输出,输入输出都是JSON对象类型。
Task可以参照其他Task的输入输出,通过${taskxxx.output}方式进行参照。 引文语法为json-path,除了最基本的${taskxxx.output}值分析方法外,还支持过滤等复杂操作。 具体请参见json-path语法。
可以在启动工作流时传递进程的输入数据,并且可以在${workflow.input}中查看任务。
任务实现原子操作的处理和流控制操作,工作流定义和描述任务的流关系,任务引用工作流或其他任务的输入和输出。 通过这些机制,conductor实现了对JSON DSL流程的说明。
三个整体的框架
主要分为几个部分:
Orchestrator:负责进程的流调度;
管理/执行服务:提供流程、任务的管理更新等操作;
任务队列:任务队列,由Orchestrator解决的待定任务将排队;
工作器:任务运行工作器,从任务队列中检索任务,并在执行服务中更新任务的状态和结果数据;
数据库:元数据运行时数据库。 保存运行时的工作流、任务等状态信息,以及流程任务定义等原始信息。
存储执行历史记录的索引数据库:
四运行模型
1任务状态转移
SCHEDULED :等待计划,task排队后还没有在poll上运行时的状态
IN_PROGRESS :执行中、轮询后执行,但尚未完成时的状态已完成:执行完成
失败:执行失败
CANCELLED :中止时,这种状态一般发生在两种情况下。
1 .手动中止进程时,运行中的task将处于这种状态;
2 .如果有多个fork分支,并且一个分支的task失败,则在另一个分支上运行的task将处于该状态;
2任务队列
的执行,除了同步的系统任务外,最先加入任务队列,是典型的生产者消费者模型。
任务队列是具有延迟、优先级功能的队列。
每种类型的任务都是单独的队列,如果配置了域和隔离组,则将其划分为多个队列以执行隔离。
decider service是生产者,根据流程结构和当前运行情况分析可执行的任务后,将其添加到队列中
任务执行机构(SystemTaskWorker、Worker )是消费者,对对应的队列进行长时间的轮询,从队列中获取任务执行
队列接口是可插件的,而conductor提供了Dynomite、MySQL和PostgreSQL的实现。
3核心功能的实现机制
conductor调度的核心是decider service,它根据当前流程的运行状态,分析要执行的任务列表,将任务排队,交给工作器执行。
decide的主要流程简化如下。 详细代码请参阅WorkflowExecutor.java的decide方法。
其中,计划任务处理流程简化如下。 详细代码请参见WorkflowExecutor.java中的scheduleTask方法。
decide的触发时间
最重要的触发时间:
新的执行开始后,会触发decide操作
系统任务完成后将触发decide操作
当工作器任务通过执行服务更新任务状态时,将触发decide操作
过程控制节点的实现机制
1 )任务映射器
每个任务有两个部分:任务映射器和任务映射器
Task :任务的执行逻辑代码。 其作用是执行Task
任务映射器:任务的映射逻辑代码。 从Task的定义结构、当前实例的执行状态等信息中返回实际需要执行的Task的列表
在典型任务中,任务映射器返回任务本身,并补充执行实例的状态信息。 但是,对控制节点来说,有不同的逻辑。2 )条件分支(SWITCH )的实现机制
根据条件判断,SWITCH用于执行不同的分支。
实际上,该节点的Task什么也不做,TaskMapper根据分支条件,判断将要进行的分支后,返回对应分支的最初的Task。
switchtaskmapper.javagetmappedtasks方法的主要代码:
//要调度的任务列表,最终返回结果
List小于Task大于taskstobescheduled新链接的List (小于;
//evalResult是分支条件变量的值(case )
//decisionCases是一个映射结构,其中key是分支的case值,value是相应分支的任务定义列表(分支中的任务定义有多个)。
//从分支变量的实际值中获取对应分支的任务定义list
小于列表的工作流任务大于所选任务=tasktoschedule.getdecisioncases ().get ) evalresult );
//default的逻辑:无法获取对应的分支或分支为空时,使用默认分支
if (所选任务==空值| |所选任务. isempty () {
selected tasks=tasktoschedule.getdefaultcase (;
}
if (选定的任务!=空值! 选择的任务. isempty (
//获取分支的第一个(下标0 )任务,返回decider service进行调度) decider将任务添加到队列中,交给工作器执行) )。
工作流任务选择任务=选择的任务. get (0;
调用了deciderService的getTasksToBeScheduled方法,使用该方法获取了任务映射器,然后调用了getMappedTasks。 这里采用递归调用方式,分析了嵌套的Task
列表小于任务大于Task任务=taskmappercontext.getdeciderservice (. gettaskstobescheduled (工作流实例、选定任务、检索计数、任务序列.检索任务);
taskstobescheduled.addall (缓存任务;
switchTask.getInputData ().put )、(hasChildren )、)真);
}
返回任务工作台排程;
3 )并行(福克斯)的实现机制
FORK用于打开多个并行分支。
实际上,该节点的Task不执行任何操作,TaskMapper返回所有并行分支的第一个Task。
forkjointaskmapper.javagetmappedtasks的主要代码:
//要调度的任务列表,最终返回结果
List小于Task大于taskstobescheduled新链接的List (小于;
//正在配置的所有fork分支
小于列表大于工作流任务大于福克斯任务=tasktoschedule.getforktasks (;
for (列表小于工作流任务)大于wfts :福克斯任务) )。
//在各分支中取第一个Task
工作流任务栏=wfts.get (0;
调用了deciderService的getTasksToBeScheduled方法,使用该方法获取了任务映射器,然后调用了getMappedTasks。 这里采用递归调用方式,分析了嵌套的Task
列表小于任务的任务2=任务管理器上下文. getdeciderservice () ) ) ) ) )。
. gettaskstobescheduled (工作流实例,wft,重试计数);
taskstobescheduled.addall (tasks 2;
}
返回任务工作台排程;总的来说,分支(SWITCH )、并行)、FORK )节点本身没有执行逻辑,返回到通过TaskMapper实际执行的Task,交给Decider Service处理。
重试的实现机制
重试及其延迟时间的设置通过任务队列的功能实现。
重试:将任务重新添加到任务队列
重试延迟时间:在添加到任务队列时设置延迟时间。 在延迟时间过后,任务才会在队列中轮询和执行
五完整性保障机制
由于在调度过程中可能会发生计算机重新启动、网络异常、JVM崩溃等意外情况,因此这些原因会导致decide进程意外终止、进程运行不完整、进程正在运行(实际上是计划中,
文/上海蓝盟 IT外包专家