开源微服务编排框架:Netflix Conductor

简介:本文主要介绍netflix conductor的基本概念和主要运行机制。

image.png

作者 | 夜阳
来源 | 阿里技术公众号

本文主要介绍netflix conductor的基本概念和主要运行机制。

一 简介

netflix conductor是基于JAVA语言编写的开源流程引擎,用于架构基于微服务的流程。它具备如下特性:

  • 允许创建复杂的业务流程,流程中每个独立的任务都是由一个微服务所实现。
  • 基于JSON DSL 创建工作流,对任务的执行进行编排。
  • 工作流在执行的过程中可见、可追溯。
  • 提供暂停、恢复、重启等多种控制模型。
  • 提供一种简单的方式来最大限度重用微服务。
  • 拥有扩展到百万流程并发运行的服务能力。
  • 通过队列服务实现客户端与服务端的分离。
  • 支持 HTTP 或其他RPC协议进行数据传送

二 基本概念

1 Task

Task是最小执行单元,承载了一段执行逻辑,如发送HTTP请求等。

  • System Task:被conductor服务执行,这些任务的执行与引擎在同一个JVM中。
  • Worker Task:被worker服务执行,执行与引擎隔离开,worker通过队列获取任务后,执行并更新结果状态到引擎。Worker的实现是跨语言的,其使用Http协议与Server通信。

conductor提供了若干内置SystemTask:

  • 功能性Task:

    • HTTP:发送http请求
    • JSON_JQ_TRANSFORM:jq命令执行,一般用户json的转换,具体可见jq官方文档
    • KAFKA_PUBLISH: 发布kafka消息
  • 流程控制Task:

    • SWITCH(原Decision):条件判断分支,类似于代码中的switch case
    • FORK:启动并行分支,用于调度并行任务
    • JOIN:汇总并行分支,用于汇总并行任务
    • DO_WHILE:循环,类似于代码中的do while
    • WAIT:一直在运行中,直到外部时间触发更新节点状态,可用于等待外部操作
    • SUB_WORKFLOW:子流程,执行其他的流程
    • TERMINATE:结束流程,以指定输出提前结束流程,可以与SWITCH节点配合使用,类似代码中的提前return语句
  • 自定义Task:

    • 对于System Task,Conductor提供了WorkflowSystemTask 抽象类,可以自定义扩展实现。
    • 对于Worker Task,可以实现conductor的client Worker接口实现执行逻辑。

2 Workflow

  • Workflow由一系列需要执行的Task组成,conductor采用json来描述Task的流转关系。
  • 除基本的顺序流程外,借助内置的SWITCH、FORK、JOIN、DO_WIHLE、TERMINATE任务,还能实现分支、并行、循环、提前结束等流程控制。

3 Input&Output

Task的输入是一种映射,其作为工作流实例化的一部分或某些其他Task的输出。允许将来自工作流或其他Task的输入/输出作为随后执行的Task的输入。

  • Task有自己的输入和输出,输入输出都是jsonobject类型。
  • Task可以引用其他Task的输入输出,使用${taskxxx.output}的方式引用。引用语法为json-path,除最基础的${taskxxx.output}的值解析方式外,还支持其他复杂操作,如过滤等,具体见json-path语法。
  • 启动Workflow时可以传入流程的输入数据,Task可以通过${workflow.input}的方式引用。

Task实现原子操作的处理以及流程控制操作,Workflow定义描述Task的流转关系,Task引用Workflow或者其它Task的输入输出。通过这些机制,conductor实现了JSON DSL对流程的描述。

三 整体架构

image.png

主要分为几个部分:

  • Orchestrator: 负责流程的流转调度工作;
  • Management/Execution Service: 提供流程、任务的管理更新等操作;
  • TaskQueues: 任务队列,Orchestrator解析出来的待执行Task会放到队列中;
  • Worker: 任务执行worker,从TaskQueues中获取任务,通过Execution Service更新任务状态与结果数据;
  • Database: 元数据&运行时数据库,用于保存运行时的Workflow、Task等状态信息,以及流程任务定义的等原信息;
  • Index: 索引数据库,用于存储执行历史;

四 运行模型

1 Task状态转移

  • SCHEDULED:待调度,task放到队列中还没有被poll出来执行时的状态
  • IN_PROGRESS:执行中,被poll出来执行但还没有完成时的状态
  • COMPLETED:执行完成
  • FAILED:执行失败
  • CANCELLED:被中止时为此状态,一般出现在两种情况:

    1. 手动中止流程时,正在运行中的task会被置为此状态;
    2. 多个fork分支,当某个分支的task失败时,其它分支中正在运行的task会被置为此状态;

image.png

2 任务队列

任务的执行(同步的系统任务除外)都会先添加到任务队列中,是典型的生产者消费者模式。

  • 任务队列,是一个带有延迟、优先级功能的队列;
  • 每种类型的Task是一个单独的队列,此外,如果配置了domain、isolationGroup,还会拆分成多个队列实现执行隔离;
  • decider service是生产者,其根据流程配置与当前执行情况,解析出可执行的task后,添加到队列;
  • 任务执行器(SystemTaskWorker、Worker)是消费者,其长轮询对应的队列,从队列中获取任务执行;

队列接口可插拔,conductor提供了Dynomite 、MySQL、PostgreSQL的实现。

3 核心功能实现机制

conductor调度的核心是decider service,其根据当前流程运行的状态,解析出将要执行的任务列表,将任务入队交给worker执行。

decide主要流程简化如下,详细代码见WorkflowExecutor.java的decide方法:

image.png

其中,调度任务处理流程简化如下,详细代码见WorkflowExecutor.java的scheduleTask方法:

image.png

decide的触发时机

最主要的触发时机:

  1. 新启动执行时,会触发decide操作
  2. 系统任务执行完成时,会触发decide操作
  3. Workder任务通过ExecutionService更新任务状态时,会触发decide操作

流程控制节点的实现机制

1)Task & TaskMapper

对于每一个Task来说,都有Task和TaskMapper两部分:

  1. Task:任务的执行逻辑代码,它的作用是Task的执行
  2. TaskMapper:任务的映射逻辑代码,它通过Task的定义配置、当前实例的执行状态等信息,返回实际需要执行的Task列表

对于一般的任务来说,TaskMapper返回的是就是Task本身,补充一些执行实例的状态信息。但是对于控制节点来说,会有不同的逻辑。

2)条件分支(SWITCH)的实现机制

SWITCH用于根据条件判断,执行不同的分支。

实际上,该节点的Task不做任何操作,TaskMapper根据分支条件,判断出要走的分之后,返回对应分支的第一个Task。

SwitchTaskMapper.java getMappedTasks方法关键代码:

// 待调度的Task list,最终返回结果
List<Task> tasksToBeScheduled = new LinkedList<>();
// evalResult是分支条件变量的值(case)
// decisionCases是一个Map结构,key为分支的case值,value为对应分支的任务定义list(分支内的任务定义会有多个)
// 根据分支变量的实际值,获取对应分支的任务定义list
List<WorkflowTask> selectedTasks = taskToSchedule.getDecisionCases().get(evalResult);
// default的逻辑:如果获取不到对应的分支或者分支为空,则用默认的分支
if (selectedTasks == null || selectedTasks.isEmpty()) {selectedTasks = taskToSchedule.getDefaultCase();
}
if (selectedTasks != null && !selectedTasks.isEmpty()) {// 获取分支的第一个(下标0)task,返回给decider service去做调度(decider会把任务添加到队列里,交给worker去执行)WorkflowTask selectedTask = selectedTasks.get(0);// 调用了deciderService的getTasksToBeScheduled方法,此方法里又获取到TaskMapper调用了getMappedTasks。这里采用了递归调用的方式,解析嵌套的TaskList<Task> caseTasks = taskMapperContext.getDeciderService().getTasksToBeScheduled(workflowInstance, selectedTask, retryCount, taskMapperContext.getRetryTaskId());tasksToBeScheduled.addAll(caseTasks);switchTask.getInputData().put("hasChildren", "true");
}
return tasksToBeScheduled;

3)并行(FORK)的实现机制

FORK用于开启多个并行分支。

实际上,该节点的Task不做任何操作,TaskMapper返回所有并行分支的第一个Task。
ForkJoinTaskMapper.java getMappedTasks关键代码:

// 待调度的Task list,最终返回结果
List<Task> tasksToBeScheduled = new LinkedList<>();
// 配置中的所有fork分支
List<List<WorkflowTask>> forkTasks = taskToSchedule.getForkTasks();
for (List<WorkflowTask> wfts : forkTasks) {// 每个分支取第一个TaskWorkflowTask wft = wfts.get(0);// 调用了deciderService的getTasksToBeScheduled方法,此方法里又获取到TaskMapper调用了getMappedTasks。这里采用了递归调用的方式,解析嵌套的TaskList<Task> tasks2 = taskMapperContext.getDeciderService().getTasksToBeScheduled(workflowInstance, wft, retryCount);tasksToBeScheduled.addAll(tasks2);
}
return tasksToBeScheduled;

总的来说,分支(SWITCH)、并行(FORK)节点本身没有执行逻辑,其通过TaskMapper返回到实际要执行的Task,然后交给Decider Service处理。

重试的实现机制

重试和其延迟时间设置,都是借助任务队列的功能实现的。

重试:将任务重新添加到任务队列

重试的延迟时间:添加到任务队列时设置延迟时间,延迟时间过后,任务才能在队列中被poll出来执行

五 完整性保障机制

由于调度过程中可能会出现因机器重启、网络异常、JVM崩溃等偶发情况,这些会导致的decide过程意外终止,流程执行不完整,展现出如流程一直运行中(实际已经没有在调度),或者其它状态错误等异常现象。

1 WorkflowReconciler

针对这种情况,conductor有一个WorkflowReconciler,会定期尝试decide所有正在运行中的流程,修复流程执行的一致性。此外,它还有一个作用是校验流程超时时间。

2 decideQueue

那么WorkflowReconciler是如何获取到当前运行中的流程呢,答案是decideQueue。
decideQueue和任务队列相同,也是一个具有延迟功能的队列,其存放的是正在执行中的流程的实例id。在任务开始执行时(包括新启动执行、重试执行、恢复执行、重跑执行等),会将实例id push到decideQueue中;在执行结束(成功、失败)时,会从decideQueue中删除实例id。

3 ExecutionLockService

WorkflowReconciler会定期尝试decide所有正在运行中的流程用于超时判断、维护流程一致性。但是流程本身正常执行也会触发decide,如果同一个执行同时触发两个decide,可能会导致状态混乱,执行卡住等问题。

conductor采用了锁来解决这个问题,其提供了单机LocalOnlyLock(基于信号量实现)、redis分布式锁(基于redission实现)、zookeeper分布式锁三种实现。

decide方法中最开始会尝试获取锁,如果获取失败则直接返回。通过锁来保障不会对同一个流程实例并发执行decide。

if (!executionLockService.acquireLock(workflowId)) {return false;
}

由于锁是可配置的,可能会导致一个误区:单台机器的话不用配置锁。其实单机也是需要配置锁的,因为WorkflowReconciler和流程正常执行会产生冲突,可能会导致偶发的流程状态混乱问题。

原文链接
本文为阿里云原创内容,未经允许不得转载。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/511884.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

直播回顾:如何对付臭名昭著的 IO 夯?诊断利器来了 | 龙蜥技术

简介&#xff1a;听到IO夯总是让人头疼&#xff0c;那有没有可以分析IO夯问题的利器&#xff1f; 编者按&#xff1a;sysAK&#xff08;system analyse kit&#xff09;&#xff0c;是龙蜥社区&#xff08;OpenAnolis&#xff09;系统运维 SIG 下面的一个开源项目&#xff0c;…

cad致命错误如何处理_Golang 如何优雅地处理错误

- 后端早读课翻译计划 第二篇- 本文提供了一个优雅的处理 Golang 中错误的方法&#xff0c;解决了 Golang error 只有字符串信息的局限性&#xff0c;提供了上下文信息、错误类型判断的功能。尽管 go 具有一个简单的错误模型&#xff0c;但是乍一看&#xff0c;事情并没有那么容…

计算机专业英语第2章测试,计算机专业英语答案

【问答题】翻译下列句子 v【文件作答】熟记计算机专业英语词汇【填空题(客观)】Choose the best one of the four answers given to fill in each blank. This chapter introduces digital computer, data types, the evolution of computers, and types of computers. 1 i…

快速云原生化,从数据中心到云原生的迁移实践

简介&#xff1a;本文将介绍在帮助用户快速完成迁云中的解决方案、最佳实践以及迁云工具。 云原生的时代已经到来&#xff0c;云原生技术正在重塑整个软件生命周期&#xff0c;阿里巴巴是国内最早布局云原生技术的公司之一。 容器服务团队在过去的几年时间内帮助很多用户成功…

实力总结四类 Bean 注入 Spring 的方式

作者 | 阿Q来源 | 阿Q说代码一提到Spring&#xff0c;大家最先想到的是啥&#xff1f;是AOP和IOC的两大特性&#xff1f;是Spring中Bean的初始化流程&#xff1f;还是基于Spring的Spring Cloud全家桶呢&#xff1f;今天我们就从Spring的IOC特性入手&#xff0c;聊一聊Spring中把…

互联网公司如何塑造一支有创业精神的技术团队?

简介&#xff1a;践行这套理论&#xff0c;一个很大的感慨&#xff1a;创业文化的探索&#xff0c;就是和一群志同道合的伙伴去不断探索未知世界&#xff0c;并实现个人与集体成长的过程。所以也非常渴望和志同道合的同学一起探讨交流&#xff01; 作者 | 岩动 引言 我们经常…

广州大学计算机网络期末考试2013,广州大学计算机网络技术试卷(A卷)

广州大学2006-2007 学年第 1 学期考试卷课程计算机网络技术考试形式(开/闭卷&#xff0c;考试/查)一、填空题(15分)1、现有一计算机要和另一设备进行通信&#xff0c;要实现此目标首先要考虑通过何种接口把计算机和相应设备连接起来&#xff1b;解决此问题属于层的任务。(2分)2…

axure中出现小手_你所不知道的15个Axure使用技巧

Axure 6.5已于4月18日发布&#xff0c;可直到上周我才发现&#xff0c;于是赶紧下载升级。等待下载的过程中&#xff0c;闲来无聊跑去看了Axure的版本历史&#xff0c;又浏览了一下官方的使用教程&#xff0c;忽然发现Axure竟如此博大精深&#xff0c;自己平时所用的功能只是皮…

阿里云全站加速DCDN升级

简介&#xff1a;相比传统CDN加速&#xff0c;全站加速DCDN具有更广阔的应用场景。在当下企业全面数字化的进程中&#xff0c;为了更全面地满足广大企业客户的个性化加速需求&#xff0c;全站加速DCDN从简单开通到个性化定制、从内容分发到安全防护&#xff0c;对客户侧的使用体…

Redis 内存满了怎么办?这样置才正确!

作者 | 码哥呀来源 | 码哥字节上回在《Redis 数据过期了会被立马删除么&#xff1f;》说到如果过期的数据太多&#xff0c;定时删除无法删除完全&#xff08;每次删除完过期的 key 还是超过 25%&#xff09;&#xff0c;同时这些 key 再也不会被客户端请求&#xff0c;就无法走…

2000坐标系高程与85高程转换_【科普】测量人必须知道的几大坐标系

导读 不了解坐标系的测绘测量人员,不是好员工!无论科研的还是外业的,亦是如此。小编今天就为大家盘点出这几大传统坐标系,各位大大赶快收藏起来吧! 1 北京54坐标系 新中国成立以后,我国大地测量进入了全面发展时期,在全国范围内开展了正规的,全面的大地测量和测图工作,…

计算机编程pdf百度云,计算机编程基础.pdf

JAVA程序设计基础• Java是完全面向对象的语言&#xff0c;所有的实现必须放在类中。• JVM是 Java 编程语言的核心。• Java 运行时环境 (JRE) 包含一方面与硬件交互、另一方面又与程序交互的 JVM 。• JDK用于开发 Java 程序。• main函数是Java应用程序执行的入口。• 掌握如…

云原生数据仓库AnalyticDB支撑双11,大幅提升分析实时性和用户体验

简介&#xff1a;2021年双十一刚刚落幕&#xff0c;已连续多年稳定支持双十一大促的云原生数据仓库AnalyticDB&#xff0c;今年双十一期间仍然一如既往的稳定。除了稳定顺滑的基本盘之外&#xff0c;AnalyticDB还有什么亮点呢&#xff1f;下面我们来一一揭秘。 作者 | Analytic…

漫画:什么是IaaS、PaaS、SaaS?

‍‍作者 | 小灰来源 | 程序员小灰假如你想要一栋属于自己的房子&#xff0c;你有什么样的选择呢&#xff1f;第一种方式&#xff0c;我们可以自己上山砍树准备木材&#xff0c;然后自己去烧制砖瓦&#xff0c;还需要自己研磨油漆等其他材料.....材料准备齐全以后&#xff0c;我…

app获取个人信息是否合法_重拳出击!42款APP过度收集用户信息被点名

驱动中国2019年9月10日消息 近年来我国不断加强对互联网应用中个人信息的保护&#xff0c;但因相关监管机制尚不健全&#xff0c;实际上多数APP并未遵循最少够用原则&#xff0c;仍存在违规收集使用个人信息现象。日前&#xff0c;广东省公安厅持续加强对超范围收集用户信息行为…

无接触式智能服务 用“减法”重塑企业前台场景

简介&#xff1a;为了更好解决企业对前台工作效率、服务体验等诉求&#xff0c;阿里巴巴企业智能事业部联合阿里行政&#xff0c;推出的“非接触式服务”——云前台&#xff0c;集物品暂存、自助领取、物品临时借用、查询周边配套信息、一键呼叫视频客服、报销单收取等功能于一…

阿里园区的这个“格子间” 成为企业高效协同新利器

简介&#xff1a;第一期《数智进化论》带你走进阿里园区的“网红”格子间——视频会议吧&#xff0c;了解它是如何提升办公空间利用率&#xff0c;解决会议室资源供给不足的问题。 会议室是企业员工进行创意、讨论、决策的重要协作场所。传统会议室数量有限、大小相对固定&…

引入的html设置utf-8,如何为default.html将字符编码设置为UTF-8?

我花了最后几个小时让我的网站验证HTML 4.01严格&#xff0c;我实际上已经取得了成功&#xff0c;但仍然有一个我无法摆脱的警告。警告是&#xff1a;字符编码不匹配&#xff01;中指定的字符编码HTTP标头(iso-8859-1)是不同于的价值元素(utf-8)。我会用这个值来自HTTP头(iso-8…

仅用一个 HTML 标签,实现带动画的抖音 Logo

作者 | 零一来源 | 前端印象今天给大家表演 仅用一个HTML标签实现带动画的抖音LOGO&#xff0c;涉及了很多知识点&#xff0c;欢迎交流讨论先上结果&#xff0c;最终实现效果如下&#xff1a;成品图还原度应该还可以吧&#xff1f;抖音Logo结构想要用CSS来画抖音的Logo&#xf…

vaex 处理海量数据_核心业务“瘦身”进行时!手把手带你搭建海量数据实时处理架构...

01 背景在线交易服务平台目的是减轻核心系统计算压力和核心性能负荷压力&#xff0c;通过该平台可以将核心系统的交易数据实时捕获、实时计算加工、计算结果保存于SequoiaDB中。并能实时的为用户提供在线交易查询服务。在线交易服务平台基于实时处理架构设计&#xff0c;通过将…