关于workflow:基于-Vue3-Element-Plus-Go-Postgres-Redis-实现的工单系统

什么是工单零碎?工单零碎是一种用于跟踪、治理和解决问题或申请的软件工具。 它通常由一个地方数据库和一个用户界面组成,用户能够通过该界面提交申请或问题,而反对人员能够应用该界面查看、调配和解决这些问题。 工单零碎能够用于各种不同的场景,例如客户反对、技术支持、设施保护等。通过应用工单零碎,组织能够更无效地解决问题和申请,并进步晋升效率,缩小不必要沟通。 演示站点:http://fdevops.com:8000 账号密码:lanyulei / lanyulei 官网地址:http://fdevops.com:8099/ 分割我:http://fdevops.com:8099/contact.html 应用工单零碎能为您带来什么?进步工作效率:工单零碎可能主动分配任务、揭示工作进度、整合资源和信息,缩小人为谬误和重复性工作,从而进步工作效率。进步客户满意度:工单零碎可能疾速响应客户需要,及时解决问题,进步客户满意度。改善合作效率:工单零碎可能在团队之间分配任务、共享信息和资源,进步合作效率,缩小误会和破绽。数据分析和报告:工单零碎可能记录工作数据、生成报表和剖析工作绩效,帮忙管理者理解团队的工作进展和瓶颈,并做出决策。总之,应用工单零碎能够进步工作效率,进步客户满意度,改善合作效率和提供数据分析和报告等益处。 工单零碎性能介绍工单零碎的性能通常包含以下几个方面: 工单治理:工单零碎可能创立、调配、跟踪和敞开工单,记录工单的状态和进度,不便管理者理解工作状态和品质。自动化工作流程:工单零碎可能自动化任务分配、揭示和审核,缩小人工干预,进步工作效率和准确性。客户服务:工单零碎可能提供客户服务,承受客户问题报告,分配任务并在工作实现后进行反馈。绩效治理:工单零碎可能记录工作数据、生成报表和剖析工作绩效,帮忙管理者理解团队的工作进展和瓶颈,并做出决策。沟通合作:工单零碎可能在团队之间共享信息和资源,进步合作效率,缩小误会和破绽。数据安全:工单零碎可能爱护数据安全,设置权限、备份数据和避免信息泄露。扩展性:工单零碎通常能够与其他软件和系统集成,满足不同团队和行业的需要。下面为大家宏观的介绍了下本工单零碎的性能,接下来咱们就更细化的来理解下我的工单零碎的性能。 工单列表依据不同的权限划分不同的页面来治理工单,别离为: 我的待办:即须要我进行解决或者审批的工单。我创立的:即由我创立的工单。我相干的:包含我创立的,须要我解决的以及我解决过的工单。所有工单:顾名思义即以后工单零碎的所有工单申请,都在此页面。每个页面,都是有多个筛选项,便于用户找到须要的工单,同时也反对表单数据的全局检索,导出等性能,十分的便捷。 模板设计器表单设计器是一种可视化工具,用于创立和设计网页表单,它能够让用户通过拖放和配置选项来疾速构建和定制表单,而无需编写HTML和CSS代码。它通常提供了各种表单元素,例如文本框、下拉菜单、单选框、复选框等,用户能够自由组合和排列这些元素,以满足不同的业务需要。 在表单设计器中,用户能够设置表单元素的款式、属性和验证规定,以确保表单的正确性和安全性。此外,表单设计器还提供了预览性能,使用户能够实时查看表单的外观和交互成果。最终,表单设计器能够将表单生成为HTML代码,不便用户将其嵌入网页中。 流程设计器流程设计器是一种可视化工具,用于创立和设计业务流程和工作流程。它通常具备直观的图形界面,以便用户能够通过拖放和连贯各种元素来构建和定义流程,例如工作、节点、分支、条件、事件等。用户能够依据业务需要来定义流程的执行程序和流程中每个步骤的行为和角色。 在流程设计器中,用户能够定义流程的流转规定、条件、触发器和流程图的款式,以便使其易于了解和治理。一些流程设计器还提供了预览性能,使用户能够实时查看流程的执行过程和后果。 流程设计器被广泛应用于各种业务场景,例如销售流程、洽购流程、工作流程等。它能够帮忙企业优化流程和提高效率,同时提供了流程监控、审批、合作等性能。流程设计器也经常和其余工具集成应用,例如CRM零碎、ERP零碎、OA零碎等。 会签会签是指在流程中须要多人参加的环节,要求所有参与者必须达成一致意见后,能力持续流程的执行。在会签环节,每个参与者须要对以后流程环节所波及的问题或决策进行探讨和表决,直到所有人就此达成一致意见。 会签是流程中的一种常见管制形式,它能够帮忙企业实现流程的民主化、科学化、高效化,同时进步流程的决策品质和透明度。 被动接单被动接单是指在流程中须要执行某个工作或工作时,工作人员能够被动抉择支付该工作或工作,而不是期待任务分配或者强制指派。在被动接单的流程中,工作或工作通常以一种公开的模式出现,工作人员能够自行抉择并支付工作。 被动接单通常利用于一些协作性较强、需求量较大的工作场景中,例如客户服务、技术支持、软件开发等畛域。通过被动接单,能够让工作人员自主抉择和治理本人的工作,进步工作效率和工作积极性。 在理论利用中,被动接单的流程通常包含以下步骤: 将工作或工作以公开的模式展现在工作列表中。工作人员浏览工作列表,并依据本人的能力和趣味被动抉择支付工作。工作人员支付工作后,能够对工作进行状态更新、备注、附件上传等操作,以便更好地跟踪和管理工作停顿。当工作实现后,工作人员能够将工作标记为已实现,并将工作后果提交给流程的下一步执行者。被动接单的流程设计须要思考多个因素,如任务分配、工作人员的权限、工作的时效性、工作量的调配等。同时,还须要对工作流程进行监控和治理,以确保流程的正确执行和工作品质的保障。 排他网关排他网关是指在流程中须要进行抉择或决策时,只能抉择一条路线继续执行的管制网关。在流程执行到排他网关时,依据条件的不同,只能抉择一条满足条件的输入门路,并将流程持续沿该门路执行,其余门路将被疏忽。 排他网关通常利用于须要进行抉择或决策的流程场景中,例如审批流程、订单解决流程等。通过排他网关,能够依据不同的条件或规定,主动分支流程,并将流程沿适合的门路疏导到下一个步骤。 在理论利用中,排他网关通常须要思考以下几个方面: 输出条件:排他网关须要依据输出条件,判断流程是否须要分支。例如,审批流程中的排他网关须要判断申请的类型,判断是否须要进行不同的审批流程。输入门路:排他网关须要定义不同的输入门路,每条门路须要定义满足的条件和执行的操作。例如,审批流程中的排他网关须要定义通过审批和驳回审批两条输入门路。默认门路:当所有门路都不满足条件时,须要定义一个默认门路,以防止流程中断或无奈执行的状况。冲突检测:排他网关须要检测不同输入门路之间是否存在抵触或反复的条件,以防止流程执行的歧义或谬误。排他网关是流程中罕用的一种管制形式,通过排他网关能够灵便管制流程的执行门路,进步流程的可控性和效率。同时,排他网关的设计和配置须要充分考虑业务需要和流程逻辑,以确保流程的正确执行和质量保证。 并行网关并行网关是指在流程中须要进行并发执行时,同时执行多个分支流程的管制网关。在流程执行到并行网关时,依据定义的输入门路,将流程分成多个分支,每个分支都能够独立执行,无需期待其余分支的执行后果。当所有分支流程都执行实现后,流程会汇聚到下一个步骤继续执行。 并行网关通常利用于流程中须要同时执行多个工作或子流程的场景,例如订单解决流程、工单解决流程等。通过并行网关,能够将流程分成多个并发的分支,进步流程的执行效率和解决能力。 并行网关是流程中罕用的一种管制形式,通过并行网关能够实现流程的并发执行和减速,进步流程的解决效率和灵活性。同时,设计和配置并行网关须要充分考虑业务需要和零碎性能等因素,以确保流程的正确执行和质量保证。 自动化工作自动化工作是指在流程中通过自动化脚本或工具,实现自动化执行的工作。在流程执行过程中,自动化工作能够主动实现一系列的操作,例如数据处理、文档生成、告诉发送、系统集成等,从而缩小人工干预和进步执行效率。 自动化工作通常利用于流程中重复性高、操作标准、数据量大或须要疾速响应的场景,例如批量数据处理、自动化测试、系统监控等。通过自动化工作,能够大幅度缩小人工操作的工夫和老本,进步流程的执行效率和精度。 在理论利用中,自动化工作须要思考以下几个方面: 脚本语言:自动化工作须要编写脚本语言或脚本程序来实现工作的自动化执行。常见的脚本语言包含Shell、Python等,依据具体的需要和零碎环境,须要抉择适合的脚本语言进行编写。数据处理:自动化工作可能须要进行大量的数据处理操作,例如数据抽取、荡涤、转换等。须要依据具体的业务需要和数据规模,抉择适合的数据处理工具和算法进行实现。集成形式:自动化工作须要与其余零碎或利用进行集成,例如通过API接口、文件传输、音讯队列等形式实现零碎之间的数据交换和通信。错误处理:自动化工作须要思考错误处理和异常情况的解决形式,例如呈现谬误时须要主动回滚、重试或告诉管理员等。自动化工作是流程自动化的重要组成部分,通过自动化工作能够大幅度提高流程的执行效率和品质。同时,设计和实现自动化工作须要充分考虑业务需要和零碎技术等因素,以确保自动化工作的正确执行和质量保证。 工作治理 工作历史 工作详情 权限治理细粒度的权力治理,包含页面按钮、API接口。 性能未介绍齐全,更多功能请拜访演示站点理解,相对让您不虚此行。 演示站点:http://fdevops.com:8000 账号密码:lanyulei / lanyulei

February 14, 2023 · 1 min · jiezi

关于workflow:Workflow的json-parser实现

Workflow中有一个小而美的json-parser,一千行代码写得十分典雅粗劣。不仅能够学习到经典的C语言写法、递归解析的架构、与内核近似的编码格调、简洁的接口设计,而且也十分不便引入我的项目中作为轻量级的json解析器。因为是开源我的项目Workflow的子模块之一,所以代码品质和开源我的项目的长期投入都有保障~~~ 围观地址:https://github.com/Barenboim/... 1、基于ANSI-C,残缺反对ECMA-404 json规范; 2、轻量级:只有json_parser.h和json_parser.c,依赖只有linux内核中的两个经典数据结构rbtree.h和list.h; 3、高性能:尽管不是最快的,但实测性能大略是cJSON的1.5倍,jsoncpp的10倍左右; 4、接口简洁,执行make命令就能够间接把现成的可执行文件parse_json和test_speed编译进去,Windows下也能够用。能够围观下test.c里的用法指南: int main (){ ... json_value_t *val = json_value_parse(buf); // 解析json文档产生json value if (val) { print_json_value(val, 0); json_value_destroy(val); // 销毁json value } ...5、C中面向对象的写法,以及相熟的linux kernel编码格调,比拟赏心悦目: /* 从json value中取得string */const char *json_value_string(const json_value_t *val);/* 从json value中取得num */double json_value_number(const json_value_t *val); /* 从json value中取得json object */json_object_t *json_value_object(const json_value_t *val);/* 返回object大小 */int json_object_size(const json_object_t *obj); /* 查找name下的value。返回json value对象 */const json_value_t *json_object_find(const char *name, const json_object_t *obj); /* 遍历json object。这不是一个函数,是一个开展成一个for循环的宏 */json_object_for_each(name, val, obj)6、外部典雅的递归解析架构: ...

January 14, 2023 · 1 min · jiezi

关于workflow:一种简洁又不失优雅的工作流极狐-flow

本文来自:万金 极狐(GitLab)解决方案专家杨周 极狐(GitLab) 高级解决方案架构师极狐(GitLab) 市场部内容团队咱们提到的 Workflow 是指什么?咱们在日常开发工作中提到的 Workflow 通常是指通过 Git(版本控制工具)实现的分布式版本控制(distributed revision control),它容许多名软件开发者,在不同的网络环境下,参加同一个软件开发我的项目。 这种工作模式,比集中式版本控制具备分布式的个性与增量版本的显著劣势,曾经成为行业内支流版本治理办法。 Git 除了最根本的推拉代码,还包含分支、tag、commit,其背地有很多最佳实际,例如: 基于哪个分支派生出新分支?合并到哪里去?如何进行代码评审?应用快进、压缩还是间接合并?什么阶段,在哪个分支上创立 tag?怎么设置 Git commit 的格局标准?这些最佳实际的汇合被称为工作流(Workflow)。 Git 在 2005 年诞生,最后目标是为了更好地治理 Linux 内核开发而设计。Git 最后只是作为一个能够被其余前端包装的后端利用而开发的,但起初 Git 内核曾经成熟到能够独立地进行版本控制。 仅有版本控制性能还不足以胜任代码托管工作,随后一款基于 Git 的在线源代码托管服务平台 GitHub 于 2008 年 2 月上线。 随着 2007 年继续集成(Continuous Integration)和 2009 年 DevOps 概念的风行,一站式 DevOps 研发平台 GitLab 于 2011 年诞生。 支流 Workflow 有哪些? 近年来,Workflow 基于各类平台疾速倒退。 用于 Linux 的内核版本管理工具 Git 举荐的工作流是 Git flow,源代码托管平台 GitHub 举荐的是 GitHub flow,而 DevOps 研发平台 GitLab 的,则是 GitLab flow。 ...

January 5, 2023 · 2 min · jiezi

关于workflow:使用-Vue3-Element-Plus-Go-重构-ferry-工单系统

应用 Vue3 + Element Plus + Go 重构 ferry 工单零碎我的项目介绍2020 年 7 月 13 日,我第一次提交了 ferry 工单零碎的代码,过后其实就是想将本人心中构思的工单零碎实现进去。出其不意的收到了大家关注,同时登上了 github 和 gitee 的榜单,让这个零碎让更多的人晓得了。 因为之前架构设计的有些许潦草,所以局部中央其实拓展起来是有点乏力的。且技术大版本的更新换代,让我有了应用新技术重构下这个零碎的想法。 上面就来简略介绍下 ferry 工单零碎,重构后的样子。 演示站点:http://fdevops.com:8000 首页首页通常是放一些工单统计相干的数据。 工单申请用户能够在这里提交工单申请。 工单列表 模板治理更多标签类型的反对,同时反对增加自定义事件、配置数据源、自定义 css 款式等。 流程治理流程治理新增了,帮助人即防止了工单有疑难不晓得找谁,反对邮件告诉及钉钉告诉。 工单解决反对工单内留言评论,解决、展现操作历史等。 简略介绍到这里,间接去演示站点体验会有更深刻的理解。 演示站点:http://fdevops.com:8000

January 5, 2023 · 1 min · jiezi

关于workflow:Flowable-服务任务执行的三种方式

后面和小伙伴们别离聊了 Flowable 中的 ReceiveTask 和 UserTask,明天咱们来看看另外一个比拟常见的 Task --> ServiceTask。 1. ServiceTaskServiceTask 从名字上看就是服务工作,它的图标个别是像上面这样: ServiceTask 个别由零碎主动实现,当流程走到这一步的时候,不会主动停下来,而是会去执行咱们提前在 ServiceTask 中配置好的办法。 2. 实际咱们通过一个简略的例子来看一下 ServiceTask 要怎么玩。 假如我有如下一个简略的流程图: 两头这个就是一个 ServiceTask。 当流程执行到 ServiceTask 的时候,具体要做哪些事件?有三种不同的形式来设置这里的工作,咱们别离来看。 2.1 监听类首先咱们能够设置一个监听类,这个监听类有一个硬性规定就是须要实现 JavaDelegate 接口,像上面这样: public class MyServiceTask implements JavaDelegate { @Override public void execute(DelegateExecution execution) { System.out.println("========MyServiceTask=========="); }}在这个监听类中咱们能够实现一些操作,通过这个 execution 也能够获取到在流程节点之间传输的变量。 这个类定义好之后,接下来咱们在流程定义的时候,配置这个类的全门路即可,如下图: 这个配置对应的 XML 内容如下: <process id="demo01" name="测试流程" isExecutable="true"> <documentation>测试流程</documentation> <startEvent id="startEvent1" flowable:formFieldValidation="true"></startEvent> <sequenceFlow id="sid-33A78082-C2FD-48BE-8B87-99FB20F0B331" sourceRef="startEvent1" targetRef="sid-6FA66E2A-F8E6-4F10-8FA2-6450408E17D8"></sequenceFlow> <serviceTask id="sid-6FA66E2A-F8E6-4F10-8FA2-6450408E17D8" flowable:class="org.javaboy.flowableidm.MyServiceTask"></serviceTask> <endEvent id="sid-A5F11956-15EA-4574-98D0-29A4E3DB5495"></endEvent> <sequenceFlow id="sid-0698809E-0A6C-4B92-A167-AE96A8CB75F2" sourceRef="sid-6FA66E2A-F8E6-4F10-8FA2-6450408E17D8" targetRef="sid-A5F11956-15EA-4574-98D0-29A4E3DB5495"></sequenceFlow> </process>小伙伴们看到,在 ServiceTask 标签中的 flowable:class="org.javaboy.flowableidm.MyServiceTask" 就示意 ServiceTask 执行的服务类。 ...

October 25, 2022 · 2 min · jiezi

关于workflow:Flowable-任务如何认领回退

@[toc]上篇文章松哥和大家分享了 Flowable 中设置工作解决人的四种形式,不过那四种形式都是针对单个工作解决人,有的时候,一个工作节点会存在多个候选人,例如 zhangsan 提交一个工作,这个工作即能够 lisi 解决,又能够 wangwu 解决,那么针对这种多个工作候选人的状况,咱们该如何解决?明天一起来看看。 1. 绘制流程图首先咱们还是应用之前旧的流程图,然而在为 UserTask 设置调配用户的时候,咱们设置多个用户,如下图: 设置实现后,咱们下载这个流程文件,来看下对应的 XML 文件,内容如下: <process id="demo01" name="demo01" isExecutable="true"> <documentation>demo01</documentation> <startEvent id="startEvent1" flowable:initiator="INITATOR" flowable:formFieldValidation="true"></startEvent> <userTask id="sid-5F901234-AFF1-480E-9D66-2D196B910BA3" flowable:candidateUsers="javaboy,zhangsan,lisi" flowable:formFieldValidation="true"></userTask> <sequenceFlow id="sid-71FB3A81-F753-419D-9A0A-2FC6E5361CED" sourceRef="startEvent1" targetRef="sid-5F901234-AFF1-480E-9D66-2D196B910BA3"></sequenceFlow> <endEvent id="sid-D0B9E5BF-8C1A-4F8F-B2C2-F423F5DC556D"></endEvent> <sequenceFlow id="sid-DEBE03CD-F247-4EF3-BB67-ABBA94739B0A" sourceRef="sid-5F901234-AFF1-480E-9D66-2D196B910BA3" targetRef="sid-D0B9E5BF-8C1A-4F8F-B2C2-F423F5DC556D"></sequenceFlow></process>小伙伴们看到,UserTask 中的 flowable:candidateUsers="javaboy,zhangsan,lisi" 就示意这个 UserTask 由 javaboy、zhangsan 和 lisi 三个用户解决,用户名之间用 , 隔开。 2. 查问工作解决人接下来咱们部署并启动下面这个流程,具体如何部署如何启动,这个在之前的文章中松哥曾经和大家聊过了,这里不再赘述。 当流程启动胜利之后,当初咱们很容易想到像之前文章那样,去查问 javaboy 须要解决的 UserTask,如下: List<Task> list = taskService.createTaskQuery().taskAssignee("javaboy").list();for (Task task : list) { logger.info("id:{};name:{};taskDefinitionKey:{}", task.getId(), task.getName(), task.getTaskDefinitionKey());}然而咱们却发现这个 SQL 执行实现后,查问不到任何数据!为什么呢?咱们来剖析下。 通过后面几篇文章的介绍,当初小伙伴们都晓得了,下面这个办法最终查问的是数据库中的 ACT_RU_TASK 表,查问的 SQL 如下: 那咱们就去查看 ACT_RU_TASK 表以及它的 ASSIGNEE_ 字段,后果如下: ...

October 11, 2022 · 3 min · jiezi

关于workflow:Flowable-设置任务处理人的四种方式

@[toc]上篇文章松哥和大家分享了 Flowable 中的 ReceiveTask,这只是流程中工作的一种,明天咱们就一起来看另外一个更为常见的 Task--UserTask。 UserTask 看名字就晓得,须要人工干预,而人工解决的形式有很多种,咱们能够设置节点是由哪个用户解决,也能够设置是由哪个用户组来解决(相当于是由哪个角色来解决),明天这篇文章我次要和大家分享设置用户的三种形式,至于如何设置用户组,这个咱们下篇文章再聊。 当初,假如我有如下一个简略的流程图: 那么我该如何设置这个用户节点的解决人呢? 1. 指定具体用户第一种形式,是咱们在绘制流程图的时候,能够选中这个节点,而后间接设置流程的解决人,像上面这样: 而后在关上的窗口中抉择固定值,设置具体调配的用户是 javaboy,如下图: 好了,当初这个节点就固定的由一个名为 javaboy 的用户去解决了。 对应的 XML 文件如下: <process id="demo01" name="demo01" isExecutable="true"> <documentation>demo01</documentation> <startEvent id="startEvent1" flowable:formFieldValidation="true"></startEvent> <userTask id="sid-5F901234-AFF1-480E-9D66-2D196B910BA3" flowable:assignee="javaboy" flowable:formFieldValidation="true"> <extensionElements> <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete> </extensionElements> </userTask> <sequenceFlow id="sid-71FB3A81-F753-419D-9A0A-2FC6E5361CED" sourceRef="startEvent1" targetRef="sid-5F901234-AFF1-480E-9D66-2D196B910BA3"></sequenceFlow> <endEvent id="sid-D0B9E5BF-8C1A-4F8F-B2C2-F423F5DC556D"></endEvent> <sequenceFlow id="sid-DEBE03CD-F247-4EF3-BB67-ABBA94739B0A" sourceRef="sid-5F901234-AFF1-480E-9D66-2D196B910BA3" targetRef="sid-D0B9E5BF-8C1A-4F8F-B2C2-F423F5DC556D"></sequenceFlow></process>在下面这段 XML 中,小伙伴们看到 UserTask 节点中有一个 flowable:assignee="javaboy",这句话就是设置这个 UserTask 的解决人。 接下来,咱们部署并启动这个流程(具体的部署启动形式能够参考本系列之前的文章),启动之后,咱们能够在数据库的 ACT_RU_TASK 表中看到,这个 UserTask 的解决人是 javaboy,如下图: 当初咱们能够通过 Java 代码去查问 javaboy 须要解决的 UserTask 了,如下: @AutowiredTaskService taskService;@Testvoid test11() { List<Task> list = taskService.createTaskQuery().taskAssignee("javaboy").list(); for (Task task : list) { logger.info("id:{},name:{}",task.getId(),task.getName()); }}这个查问,实质上其实就是去 ACT_RU_TASK 表中查问的,咱们来看看执行的 SQL: ...

October 10, 2022 · 2 min · jiezi

关于workflow:Flowable-中-ReceiveTask-怎么玩

在之前的案例中,松哥和大家举例最多的 Task 次要是 UserTask 和 ServiceTask,ReceiveTask 尽管也和大家提过然而没有认真讲过,明天咱们就来捋一捋 ReceiveTask 在 Flowable 中到底怎么玩。 1. 应用场景接受任务(Receive Task),接触过 Flowable 的小伙伴应该是见过或者据说过,它的图标如下图: ReceiveTask 能够算是 Flowable 中最简略的一种工作,当该工作达到的时候,它不做任何逻辑,而是被动地期待用户 Trigger。 ReceiveTask 往往实用于一些不明确的阻塞,例如:一个简单的计算须要期待很多条件,这些条件是须要人为来判断是否能够执行,而不是间接执行,这个时候,工作人员如果判断能够持续了,那么就 Trigger 一下使流程持续向下执行。 基于以上介绍,ReceiveTask 还有一个中文名字叫做期待工作,也就是说,流程走到 ReceiveTask 这个节点的时候,就卡住了,须要用户手动点一下,流程才会持续向下走。 2. 实际2.1 绘制流程图咱们绘制一个简略的流程图来看下 ReceiveTask 到底是啥样子,流程图如下: ReceiveTask 图标上有一个信封。 小伙伴们绘制的时候,首先抉择用户工作: 而后点击设置按钮,将用户工作切换为 ReceiveTask 即可: 绘制实现后,咱们下载这个流程图对应的 XML 文件。 来看看,带 ReceiveTask 的流程图是上面这样的: <process id="receiveTask_demo" name="接管工作测试流程" isExecutable="true"> <documentation>接管工作测试流程</documentation> <startEvent id="startEvent" flowable:formFieldValidation="true"></startEvent> <sequenceFlow id="sid-9E7B327E-EFC8-4D29-8C6F-157D5E1B7A4E" sourceRef="startEvent" targetRef="todaySales"></sequenceFlow> <receiveTask id="todaySales" name="统计今日销售额"></receiveTask> <receiveTask id="sendMsg" name="发送今日销售业绩给老板"></receiveTask> <endEvent id="endEvent"></endEvent> <sequenceFlow id="s2" sourceRef="todaySales" targetRef="sendMsg"></sequenceFlow> <sequenceFlow id="s3" sourceRef="sendMsg" targetRef="endEvent"></sequenceFlow></process>2.2 部署这个松哥在之前的文章中曾经重复介绍过屡次了,这里就不再赘述了,大家参考咱们之前的文章部署并启动下面这个流程。 2.3 剖析当流程启动之后,依照咱们后面文章的剖析,咱们先去数据库中 ACT_RU_TASK 表进行查看,发现该表空洞无物。也就是 ReceiveTask 并不会被记录在 ACT_RU_TASK 表中,他们只是单纯的被记录在 ACT_RU_EXECUTION 表中,因为在该表中,咱们能够查看 ReceiveTask 的记录。 ...

October 9, 2022 · 1 min · jiezi

关于workflow:如何使用流程-中的-DataObject-并为流程设置租户

不晓得小伙伴们有没有注意过,在 Flowable 流程图的绘制过程中,咱们能够编写一个名为 dataObject 的元素,这个元素能够指定变量的 id、名称以及数据类型等各种属性,并且在流程实例启动的时候,会主动将 dataObject 元素的信息转换为流程实例变量,这个货色也蛮好玩的,明天松哥就率领小伙伴们来捋一捋 Flowable 中的 dataObject。 1. 增加 dataObject首先咱们来看下,在流程绘制的过程中,如何去增加 dataObject 对象。 IDEA 上的 Flowable 流程图绘制插件中还不能增加 dataObject 属性,这个须要咱们去 flowable-ui 中去增加。 咱们来轻易绘制一个如下这样简略的流程图: 看过松哥之前几篇文章的小伙伴应该对这张图很相熟了,松哥这里也不多说。 我当初就想给这个流程图,增加 dataObject 属性,形式如下: 首先关上流程图,不要抉择任何节点,在下方能够找到数据对象属性,如下图: 点击之后,就能够增加 dataObject 了,如下: 配置实现之后,点击保留按钮。而后咱们下载这个流程图,下载之后,关上,咱们会发现这次的 XMl 节点比之前的 XML 节点多进去了如下一些内容: <dataObject id="name" name="流程绘制人" itemSubjectRef="xsd:string"> <extensionElements> <flowable:value>javaboy</flowable:value> </extensionElements></dataObject><dataObject id="site" name="流程作者网站" itemSubjectRef="xsd:string"> <extensionElements> <flowable:value>www.javaboy.org</flowable:value> </extensionElements></dataObject><dataObject id="date" name="流程绘制工夫" itemSubjectRef="xsd:datetime"> <extensionElements> <flowable:value>2022-09-23T00:00:00</flowable:value> </extensionElements></dataObject>2. 查问 dataObject接下来,依照之前文章介绍的形式,咱们先来部署并启动这个流程图。 当流程部署胜利之后,咱们能够在 ACT_RU_VARIABLE 表中查看到 dataObject 中的数据,如下图: 能够看到,dataObject 的数据是和执行实例 ID 以及流程实例 ID 相干的。 接下来,咱们能够通过如下形式来查问 ACT_RU_VARIABLE 表中的数据: @Testvoid test08() { List<Execution> list = runtimeService.createExecutionQuery().list(); for (Execution execution : list) { DataObject data = runtimeService.getDataObject(execution.getId(), "流程绘制人"); logger.info("key:{},name:{},value:{}",data.getDataObjectDefinitionKey(),data.getName(),data.getValue()); }}这里打印进去的信息就是咱们刚刚在定义的时候配置的所有流程信息了。 ...

October 9, 2022 · 1 min · jiezi

关于workflow:Flowable-流程实例的挂起暂停与激活

明天来和小伙伴们聊一聊流程的挂起和激活。 这块实际上波及到两局部内容: 流程定义的挂起和激活。流程实例的挂起和激活。一个定义好的流程,如果挂起了,那么就无奈据此创立新的流程。 一个流程实例如果挂起了,那么就无奈执行流程中的工作。 小伙伴们留神辨别这两个概念(看了后面几篇文章的小伙伴,应该对于这两个概念不在话下了)。 咱们别离来看。 1. 流程定义的挂起与激活1.1 查问是否挂起对于一个定义好的流程,咱们能够通过如下办法来查看这个流程是否挂起: @Testvoid test05() { List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().list(); for (ProcessDefinition processDefinition : list) { String id = processDefinition.getId(); boolean suspended = repositoryService.isProcessDefinitionSuspended(id); if (suspended) { logger.info("流程定义 {} 已挂起",processDefinition.getName()); }else{ logger.info("流程定义 {} 未挂起",processDefinition.getName()); } }}这个查问 SQL 波及到的表是 ACT_RE_PROCDEF,该表中有一个名为 SUSPENSION_STATE_ 的字段,该字段示意这个流程是否挂起。如下图: 1 示意流程没有挂起。 1.2 挂起执行如下办法,能够挂起一个流程定义,如下: @Testvoid test06() { List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().list(); for (ProcessDefinition pd : list) { repositoryService.suspendProcessDefinitionById(pd.getId()); }}挂起的原理其实很简略,就是去 ACT_RE_PROCDEF 表中,将 SUSPENSION_STATE_ 字段的值设置为 2,就示意这个流程定义挂起了,咱们能够看下流程定义挂起时执行的 SQL: ...

October 8, 2022 · 2 min · jiezi

关于workflow:Flowable-流程部署与删除

本文咱们一起来看看流程的部署等细节问题。 其实当咱们应用了 Spring Boot 之后,默认状况下流程是会主动部署的,基本上不须要咱们额定做什么事件。不过这些操作里还是有不少细节,明天松哥就来带大家一起来梳理一下。 1. 默认行为首先咱们先来梳理一下默认行为。 默认状况下,咱们放在 resources/processes 目录下的所有流程文件会主动被部署,流程文件的后缀有两种模式 bpmn20.xml 或者 bpmn。当然,无论是寄存流程文件的地位,还是流程文件的格局,都是能够定制的,波及到的属性次要有三个,可在 application.properties 中进行配置: flowable.check-process-definitions=falseflowable.process-definition-location-prefix=classpath*:/processes/flowable.process-definition-location-suffixes=**.bpmn20.xml,**.bpmnflowable.check-process-definitions:这个示意是否在我的项目启动的时候,去查看文件目录是否有对应的流程文件,该属性为 true 示意如果有流程文件就主动部署,false 示意不查看,那么也就不会主动部署。flowable.process-definition-location-prefix:这个是流程文件的地位,默认就是 classpath*:/processes/,当然开发者也能够进行配置。flowable.process-definition-location-suffixes:这个是流程文件的后缀,默认有两个,别离是 **.bpmn20.xml 和 **.bpmn,当然开发者也能够进行配置。这个配置应该没啥好说的。 2. 动静部署有的时候,咱们的流程可能并不是提前设计好的,而是我的项目启动之后,动静部署的,例如我的项目启动胜利之后,动静上传一个流程的 XML 文件进行部署,这也是一种比拟常见的场景,对于这种状况,咱们能够依照如下形式进行部署: @RestControllerpublic class ProcessDeployController { @Autowired RepositoryService repositoryService; @PostMapping("/deploy") public RespBean deploy(MultipartFile file) throws IOException { DeploymentBuilder deploymentBuilder = repositoryService.createDeployment() .category("javaboy的工作流分类") .name("javaboy的工作流名称") .addInputStream(file.getOriginalFilename(), file.getInputStream()) .key("javaboy的工作流key"); Deployment deployment = deploymentBuilder .deploy(); return RespBean.ok("部署胜利",deployment.getId()); }}我这里给了一个简略的文件上传接口,对于文件上传局部我就不多说了。咱们来看下流程部署: 首先通过 repositoryService.createDeployment() 办法来创立一个流程部署构建器,即 DeploymentBuilder。接下来为 DeploymentBuilder 设置分类、名称以及 key 等属性。要害的办法是 addInputStream,通过该办法去指定流程文件。官网的提供的指定流程文件的形式有好几种;除了 addInputStream 之外,另外还有一个 addString,这个就是将流程文件转为一个字符串传入进来;addBytes 是将流程文件转为字节数组传进来;addClasspathResource 办法则是间接从 classpath 目录上来加载流程文件,这几个办法依据本人的应用场景抉择一个适合的办法去调用即可。这里有一个须要跟大家强调的中央,就是 addInputStream/addBytes/addString 等办法都须要设置资源名,这个名称是能够随便设置的,然而留神名称的后缀,须要是 bpmn20.xml 或者 bpmn,否则流程没有部署。为什么流程名后缀要是 bpmn20.xml 或者 bpmn 呢?参考第一大节。3. 表剖析在咱们的流程部署过程中,一共有三张表参加到咱们的工作中了,尽管松哥之前曾经写过文章和大家梳理 flowable 中各个数据表的作用,不过过后只是大抵上介绍了一下,没有细说,这次咱们就先来看看这次波及到的三张表。 ...

September 26, 2022 · 3 min · jiezi

关于workflow:手把手教大家编译-flowable-源码

要说这个编译源码其实没什么技术含量,然而因为国内的网络问题,Spring 等各种常见框架的源码编译都变成了一个有技术含量的工作,你得学会去解决各种在编译的过程中可能呈现的问题。 明天松哥就来和大家聊一聊 flowable 源码编译,其实次要是和大家说说这里的几个坑。 1. 下载源码这个简略,大家间接从 GitHub 上将源码 clone 下来即可: git clone git@github.com:flowable/flowable-engine.git这一步比拟容易,大家应该都不存在问题。 2. IDEA 关上我的项目因为这个源码也是一个 Maven 工程,所以接下来间接 IDEA 关上源码即可。 松哥亲测,master 分支上的代码有点问题,所以倡议大家切换到一个稳固的版本上再去编译。 官网目前在 GitHub 上公布的最新 release 版本是 6.7.2 这个版本,所以为了源码编译顺利,接下来在右下角找到 6.7.2 这个版本,并切换: 切换实现之后,接下来咱们要先来看看源码中每个目录都是干嘛的。 distrodocker:这个里边放的是将 flowable 构建成 docker 镜像的脚本。docs:这个是文档。在 docs/docusaurus/docs 目录下有官网曾经构建好的现成的脚本,咱们也能够执行 docs/userguide/src/zh_CN/form 等目录下的脚本文件,构建本人须要的文档。一般来说不须要,间接看官网文档就够用了。ide-settings:这个目录下放的是 Eclipse 和 IDEA 中的配置文件,辅助开发用的,然而感觉理论作用无限,咱们平时开发也很少导入这两个配置,大家理解即可。k8s:看目录就晓得,这个里边放的是 flowable 反对 K8s 的一些脚本和配置。modules:flowable 中的所有外围性能代码都在这个里边了。qa:这个里边是 flowable 各种各样的配置模版,不过咱们当初基本上都是 Spring Boot 开发,很多时候并不需要手动再去配置什么,都是间接上来写业务就行了,所以这些配置模版大家理解下即可。scripts:这个目录下放了一些罕用的脚本,例如执行 build-all.sh 脚本用来构建我的项目。tooling:这个目录中的内容给出了一个单元测试的模版。LICENSE:开源协定等。README.md:介绍文档。好了,整体上理解了之后,当初大家晓得,modules 目录才是外围。 不过,因为模块较多,IDEA 不肯定总是可能辨认出所有的 Maven 我的项目,如果一个我的项目的 pom.xml 是红色而不是蓝色,就阐明 IDEA 没能辨认进去这个 Maven 我的项目,像上面这样: ...

September 15, 2022 · 2 min · jiezi

关于workflow:一个不用写代码的案例来看看Flowable到底给我们提供了哪些功能

@[toc]其实松哥之前曾经写过文章和大家介绍了 flowable-ui 的玩法了,这是官网提供的一个工具,这个工具不仅能够用来绘制流程图,还能够用来部署一个流程利用,通过这个流程利用咱们能够体验一把 flowable 流程引擎到底是干嘛的,解决了咱们的哪些问题,并且这个体验是不须要写代码的,对于一些对 flowable 没有根底的小伙伴而言,我感觉这个很好。 所以明天我想再带大家体验一把 flowable 的性能,可能有小伙伴说,咱们上次不是曾经体验过了么,上次体验的比较简单,没有表单性能,明天我想联合表单性能来和大家捋一捋 flowable-ui 的性能,特地好玩。 1. Flowable-UIFlowable-UI 说白了就是一堆 Web 利用,提供了四方面的性能: Flowable IDM: 身份治理利用。为所有 Flowable UI 利用提供单点登录认证性能,并且为领有 IDM 管理员权限的用户提供了治理用户、组与权限的性能。Flowable Modeler: 让具备建模权限的用户能够创立流程模型、表单、抉择表与利用定义。Flowable Task: 运行时工作利用,这个提供了启动流程实例、编辑工作表单、实现工作,以及查问流程实例与工作的性能。Flowable Admin: 治理利用。让具备管理员权限的用户能够查问 BPMN、DMN、Form 及 Content 引擎,并提供了许多选项用于批改流程实例、工作、作业等。治理利用通过 REST API 连贯至引擎,并与 Flowable Task 利用及 Flowable REST 利用一起部署。简略来说: 创立用户、调配角色用 Flowable IDM。画流程图用户 Flowable Modeler。测试、体验流程用 Flowable Task。后盾治理相干的用 Flowable Admin。2. 装置形式在之前的版本中,后面说的这几个利用都是不同的 war 包,部署和拜访都十分麻烦,不过当初,官网将之前的 5 个 war 整合成一个了,所以当初拜访就非常容易了。 2.1 运行 war 包因为这些利用是基于 Spring Boot2.0 开发的,因而也能够间接作为独立利用来间接运行,通过执行 java -jar xxx.war 的形式来启动这些利用。 ...

September 14, 2022 · 2 min · jiezi

关于workflow:请假要组长和经理同时审批该怎么办来看看工作流中的会签功能

@[toc]明天松哥和小伙伴们介绍一下 Spring Security 中另外一个好玩的会签性能。 会签的意思就是,在一个流程中的某一个 Task 上,这个 Task 须要多个用户审批,当多个用户全副审批通过,或者多个用户中的某几个用户审批通过,就算通过。这就是咱们说的 Flowable 中的会签性能! 例如咱们之前的销假流程,假如这个销假流程须要组长和经理都审批了,才算审批通过,那么咱们就须要设置这个 Task 是会签节点。 以咱们之前的销假流程为例,我和大家演示一下咱们这次要实现的成果。 首先员工提交销假申请,能够提交给多个审批人: 提交胜利之后,员工的历史销假列表中,能够看到刚刚提交的销假申请,然而抉择的三个审批人都是灰色的,示意三个人都还没有审批。 接下来,以 javaboy 的身份登录到零碎中,就能够看到刚刚用户提交的销假申请,而后进行审批。 审批实现后,以 zhangsan 的身份登录到零碎中,就能够看到 javaboy 曾经实现审批了,等三个人都实现审批之后,这个销假流程的状态也就会变成已通过,要是三个人中有一个人点击了回绝,那么这个销假流程的状态就会变为已回绝。 好啦,这就是咱们本文要实现的一个性能。本文也是基于之前的文章实现,如果小伙伴们还没看过松哥之前发的对于 Flowable 流程引擎的文章,能够在公众号江南一点雨上先翻一下。 1. 会签流程图首先咱们来画一下这个销假流程图,这个流程图基本上还是和之前的一样,如下图: 这跟咱们之前的流程图有两个不一样的中央: 首先就是最最外围的的这个批准或者回绝的节点,这个节点上面多个三个竖线,这三个竖线的意思就是多个用户审批时是并发执行的,相互之间没有先后顺序,还有一种是三个横线,三个横线的意思是多个用户程序执行。当然,这里不是说流程图上多三个竖线就行了,还须要略微配置一下,如下: 这里配置的属性次要有五个: 多实例类型:这个选项次要有两个,别离是 Parallel 和 Sequential,示意并发执行还是程序执行,抉择是 Parallel 就是多个用户并发执行,相互之间没有先后顺序,抉择 Sequential 则是程序执行,多个用户之间有先后顺序。汇合(多实例):这个中央我配置了一个 ${userTasks},这个示意当流程执行到这个节点的时候,我会传进来一个变量,这个变量的名字是 userTasks,这个变量中蕴含了所有要审批这个 Task 的用户名。元素变量(多实例):因为下面的是一个汇合,这里配置的则是汇合中每一个元素的变量名,这就相似于 Java 里加强 for 循环的变量名。实现条件(多实例):这里我配置的值是 ${nrOfCompletedInstances== nrOfInstances},波及到两个变量,nrOfCompletedInstances 这个示意曾经实现审批的实例个数,nrOfInstances 则示意总共的实例个数,也就是当实现审批的实例个数等于总的实例个数的时候,这个节点就算执行完了,换句话说,也就是 zhangsan 将销假申请提交给 javaboy 和 lisi,必须这两个人都审批了,这个节点才算执行完。另外这里还有一个内置的变量可用就是 nrOfActiveInstances 示意未实现审批的实例个数,只不过在本案例中没有用到这个内置变量。调配用户:这个是说这个 Task 的执行人,当然就是咱们后面配置的 userTask,也就是从汇合中拿进去的每一个元素的变量名。去掉了审批通过之后的 UserTask。在之前的销假流程图中,当销假审批通过之后,发送了销假通过告诉之后,还会进入到一个 UserTask 流程中,这里为了不便,我把这个流程删掉了。 好啦,这就是新流程图和以前旧流程图之间的一个区别,当初咱们来看下这个流程图对应的 XML 文件: ...

September 8, 2022 · 4 min · jiezi

关于workflow:Flowable-79-张表都是干嘛的

@[toc]当咱们应用 Flowable 流程引擎的时候,尽管咱们应用的是各种 API,然而小伙伴们都晓得,这些 API 实质上操作的都是底层的数据表,Flowable 默认一共生成了 79 张数据表,理解这些数据表,有助于咱们更好的了解 Flowable 中的各种 API,因而明天松哥就来和大家捋一捋 Flowable 中的数据表都有哪些,以及这些表都是干嘛用的。 当初咱们基本上都是 Spring Boot 工程了,在 Spring Boot 工程中,只有咱们增加了 Flowable 的仍然,而后启动我的项目,零碎就会主动帮咱们创立 79 张表,查问 SQL 如下: SELECT COUNT(*) TABLES, table_schema FROM information_schema.TABLES WHERE table_schema = 'flowable02' GROUP BY table_schema; 这里显示了 82 张表,是因为我本人手动创立了三个跟用户相干的表,其余 79 张表都是 Flowable 主动创立的。好了,接下来咱们就对这 79 张表进行一个简略的分类整理。 ACT_APP_*(5)ACT_CMMN_*(12)ACT_CO_*(3)ACT_DMN_*(6)ACT_EVT_*(1)ACT_FO_*(6)ACT_GE_*(2)ACT_HI_*(10)ACT_ID_*(9)ACT_PROCDEF_*(1)ACT_RE_*(3)ACT_RU_*(13)FLW_CHANNEL_*(1)FLW_EV_*(2)FLW_EVENT_*(3)FLW_RU_*(2)* 是通配符,前面的数字示意这种类型的表有多少个。 大抵看一下,其实还是有很多法则的。 最显著的法则就表名通过两个 _ 隔开成了三局部,接下来咱们就以此为线索,一部分一部分来讲。 1. 表名前缀首先搭建看这个表的前缀,分了两种: ACT_FLW_松哥在之前的文章中曾经和大家介绍过了,Flowable 是基于 Activiti 开发进去的流程引擎,所以咱们在很多中央都还能看到 Activiti 的影子,这个表名中 ACT_ 就是 Activiti。 具体来说,与 Flowable 开源代码库相干的数据库表名以 ACT_ 结尾。特定于 Flowable Work 或 Engage 的数据库表以 FLW_ 前缀结尾。 ...

September 7, 2022 · 2 min · jiezi

关于workflow:种草两个可以画-flowable-流程图的-Vue-库

之前松哥发了一篇文章和小伙伴们介绍了前端的 bpmn.js 这个库,利用这个库咱们能够本人将绘制流程图的性能嵌入到咱们的我的项目中。 然而,这个库默认是给 Camunda 设计的,所以画进去的流程图导出来的 XML 文件无奈间接应用,必须要做一些深度定制,能力将 XML 文件转为 Flowable 流程引擎可用的 XML 文件。这个深度定制太太太麻烦了。 所以我就在想前端有没有现成的库,能够间接用来绘制 Flowable 流程图的?找来找去,找到了两个,这两个的类似度还蛮高的,不过这两个都有一个问题,那就是都是基于 Vue2 开发的,在 Vue3 中用不了,算了,作为一个工具,Vue2 就 Vue2 吧,忍了。毕竟我也不是业余的前端工程师,把握的前端技能能满足我后端的需要也就足够了,要是业余的前端工程师,我必定把 bpmn.js+Vue3 整的明明白白了。 好啦,接下来就不废话了,跟小伙伴们介绍一下这两个能够绘制 Flowable 流程图的前端库。 workflow-bpmn-modelerworkflow-bpmn-modeler 基于 Vue 和 bpmn.io@7.0,实现了 flowable 的工作流设计器。应用这个流程绘制工具,倡议采纳 flowable6.4.1 版本,flowable6.4.2 版本开始进行商业化重构,为了不便刨码学习,举荐应用 flowable6.4.1 版本。 这个用法其实很简略,首先咱们创立一个 Vue2 的我的项目,留神 Vue 的版本不要选错了,我的项目创立好之后,增加 workflow-bpmn-modeler 依赖,执行如下任意命令增加: npm i workflow-bpmn-modeler或者: yarn add workflow-bpmn-modeler增加实现后,package.json 内容如下: { "name": "bpmn_demo02", "version": "0.1.0", "private": true, "scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build" }, "dependencies": { "core-js": "^3.8.3", "element-ui": "^2.15.9", "vue": "^2.6.14", "vue-router": "^3.5.1", "workflow-bpmn-modeler": "^0.2.8" }, "devDependencies": { "@vue/cli-plugin-babel": "~5.0.0", "@vue/cli-plugin-router": "~5.0.0", "@vue/cli-service": "~5.0.0", "vue-template-compiler": "^2.6.14" }}留神看版本号。 ...

September 7, 2022 · 2 min · jiezi

关于workflow:Workflow的计算调度算法

Workflow的计算调度算法让大家好奇了这么久,明天终于写被cue到最多的话题:Workflow的计算调度,包含独创的调度算法与相干数据结构。P.S. 原文写于2022年5月份~C++ Workflow作为一个异步调度编程范式,对调度的拆解是有几个档次的: 用户代码层:提供工作流级别的结构化并发,包含串并联、DAG和复合工作等,用于治理业务逻辑,组织要做的事件的依赖关系;资源管理层:对不同资源外部做了协调和治理,比方网络、CPU、GPU、文件IO等,用起码的代价、做最高效、最通用的资源复用。明天就重点介绍一下,Workflow外部独创的计算调度算法,包含Executor模块(仅200行代码)及相干模块,整体是如何治理计算资源、协调不同计算工作,从而做到无论工作耗时长短,都能够尽可能平衡调度的最通用的计划。 而且看完之后,也能够对上一篇《一个逻辑齐备的线程池》中始终强调的生命周期有一个更好的了解。架构设计始终要强调每一个模块自身做到齐备和自洽,是因为更有利于演化出下层模块。 https://github.com/sogou/workflow/blob/master/src/kernel/Executor.cc 1. 计算调度面临的问题无论是用何种计算硬件,计算调度要解决的问题是: 充沛应用资源;不同类别的工作的资源分配;优先级治理;第一点很好了解,以CPU为例,只有来工作了就要尽量跑满CPU上的若干核。 第二点,不同类别是比方:每件事情由3种步骤 A->B->C 组成,消耗的计算资源是1:2:3,简略的做法是能够别离给予3个线程池,线程比例1:2:3(假如24核的机器,咱们能够别离把3个线程池中的线程数配置为4,8,12)。 但因为线上环境是复杂多变的如果消耗资源变成了7:2:3,固定线程数计划显然不可取,不改变代码是难以匹配这样的情况。 这么做的另一个弊病是,如果一批提交100个a,那么显然只有4个线程能够工作,难以做到“资源利用即用”; 还有没有解决办法呢?更简单地,能够引入动静监测耗时,然而引入任何简单计划都会有新的overhead,绝大部分状况下这些都是节约。 持续看第三点,优先级治理是比方:还是 A->B->C 三种工作。当初减少了一个D,我想要尽快被调起来,简略的做法往往是给所有工作一个优先级编号,比方1-32。 但这并不是短暂的解决办法,编号是固定的总会往更高优的用完,而且工作本人都是贪婪的,只有有最高优先级,最终大家都会卷起来(不是 咱们须要的,是一个灵便配置线程比例、充沛调度CPU、且能够偏心解决优先级的计划。 2. 翻新的数据结构:多维调度队列Workflow外部简直所有的计划都是往通用了做,对于CPU计算,则是:全局一个线程池,和对立的治理形式。应用上,计算工作只须要带一个队列名,即可交给Workflow帮你做到最平衡的调度。 基本原理图如下: Executor外部,有一个线程池和一个根本的主队列。而每个工作自身,同时也是属于一个ExecQueue,能够看到其构造是一组以名字辨别的子队列。 这种数据结构的组合,能够做到以下三点: 首先,只有有闲暇计算线程可用,工作将实时调起,计算队列名不起作用。当计算线程无奈实时调起每个工作的时候,那么同一队列名下的工作将按FIFO的程序被调起,而队列与队列之间则是平等看待。 例如,先间断提交n个队列名为A的工作,再间断提交n个队列名为B的工作。那么无论每个工作的cpu耗时别离是多少,也无论计算线程数多少,这两个队列将近偏向于同时执行结束。 这个法则能够扩大到任意队列数量以及任意提交程序。别离来看看算法是什么。 第一点:Executor的线程不停从Executor外部的主队列中拿工作进去执行; 第二点:线程从主队列把工作取走、并筹备执行工作之前,也把工作从它本人的子队列里拿走。并且,如果该子队列前面还有工作,就把下一个工作进去,放到主队列中。 第三点:内部用户给Workflow提交工作的时候,Workflow会先把工作按名字放到子队列。并且如果发现这是子队列中的第一个工作(阐明方才子队列是空的),便立即提交到主队列中。 算法自身相当简略,而提交工作时,只须要给调度器轻微的领导,既队列名(对应Executor的一个ExecQueue),无需指定优先级或计算工夫预估等信息。 当咱们收到的A, B, C工作数足够多而且数量相等,无论工作以什么程序达到,也无论每个(留神是每个而不是每种)工作的计算工夫多少,A, B, C三个子队列将同时计算实现。 而主队列长度,永远不超过子队列的个数,且主队列中,每个子队列的工作永远只有一个,这是算法的必然结果。 3. 源码简析咱们用最简略的WFGoTask为例子,把形象的调度算法从外到里一层层落实到代码上。 1) 用法示例void func(int a);// 应用时WTGoTask *task = WFTaskFactory::create_go_task("queue_name_test", func, 4); task->start();2) 派生关系理解过Workflow工作的小伙伴肯定晓得,Workflow任何工作都是行为派生,而两头有一层,是根本单元,即由SubTask和具体执行单元双派生,这样既能够让下层工作被SubTask串到工作流里、也能够做具体执行单元做的事件。 对计算调度来说,具体执行单元那必定是每个能够被线程调度起来的计算工作。 咱们能够看到WFGoTask是从ExecRequest派生的,而ExecRequest就是执行的根本单元。(温习到网络层面,根本单元是CommRequest,一个代表执行,一个代表网络,对称性无处不在~)关上src/kernel/ExecRequest.h文件能够找到它,这里只看dispatch()里做了什么: // 这里能够看到,具体执行单元是ExecSession,它负责和Executor等打交道class ExecRequest : public SubTask, public ExecSession {public: virtual void dispatch() { if (this->executor->request(this, this->queue) < 0) ... }dispath()做的事件,就是把本人和本人的队列,通过request()接口提交到Executor。 ...

August 1, 2022 · 1 min · jiezi

关于workflow:工作流引擎在vivo营销自动化中的应用实践-引擎篇03

作者:vivo 互联网服务器团队- Cheng Wangrong本文是《vivo营销自动化技术解密》的第4篇文章,剖析了在营销自动化业务引入工作流技术的背景和工作流引擎的介绍,同时介绍了几种业界风行的开源工作流引擎特点,以及在我的项目自研开发过程中的设计思路和总结思考。 《vivo营销自动化技术解密》系列文章: vivo营销自动化技术解密|开篇 设计模式如何晋升 vivo 营销自动化业务扩展性 | 引擎篇01 状态机引擎在vivo营销自动化中的深度实际 | 引擎篇02 一、业务背景营销自动化平台能够反对不同用户生命周期的流动旅程策略配置 ,依据用户触发的不同流动行为,进行差异化的营销触达计划。同时各种类型流动的具体执行过程中也有不同的业务解决流程(比方审批流程和业务流转)。 业务流程简单多样,需要变更频繁,我的项目开发过程中会有以下痛点: 我的项目交付周期长:一个残缺的业务流程须要从头开始按版本迭代,开发工夫长,老本高。性能反复开发测试:业务之间会掺杂着很多共性的流程,导致大量重复性开发测试工作,效率低。保护老本高:随着我的项目业务的逐渐倒退,业务流程逐渐积攒,可维护性降落,零碎改变牵一发而动全身。如何将业务逻辑从控制流中剥离进去,让产研人员更聚焦于业务的实现是须要重点解决的问题。而传统OA畛域应用的是久经考验的业务流程治理解决方案 —— 工作流(Workflow)。工作流是一套工业级的解决方案,由工作流治理联盟(WfMC)制订了一系列的规范。 二、工作流介绍2.1 工作流定义工作流(Workflow)—— 对工作流程及其各操作步骤之间业务规定的形象,将流程中的工作组织逻辑和规定进行建模,交由计算机进行主动解决。 工作流的实质思维是:通过预约义的工作流程模板,对事实流动进行实例化的过程。简略说就是通过预设的格局或者可视化配置好流程的模板(比方一种分享流动的运行流程模板),应用时通过该模板结构出一个流程实例对象,通过实例对象实现流动运行跟踪和回溯。 2.2 工作流参考模型WfMC工作流治理联盟为工作流制订了参考模型,其外围就是两头的工作流引擎,工作流引擎提供流程定义工具(接口1)、给使用者提供信息查问(接口2)、调用内部利用(接口3)、整合其余工作流(接口4)和监控治理(接口5)的能力。 对于大多数工作流产品而言,重点关注的是接口1和接口2的实现。 2.3 工作流引擎要害个性流程可视化提供可视化的流程搭建,流程视图查看能力,以及实时观测工作运行能力。 业务可编排复用将公共业务进行组件化,能够反对工作的自在编排,自在搭建出适宜的业务的不同流程。 业务和管制拆散将流程的管制(如流转、判断、循环、重试等)的工作交由工作流负责,让使用者聚焦于外围业务逻辑。 2.4 工作流引擎的类型对于工作流的类型没有专门的规范,依照流程工作节点个性能够分为: 程序工作流程序工作流的运行形式相似一种特定的流程图,上一个流程工作实现后顺次进入下一个流程工作,过程不可逆。 状态机工作流状态机工作流偏重关注的是流程工作的状态,驱使工作状态发生变化的因素个别为内部事件,即事件驱动的形式,驱使工作节点从一个状态运行到另外一个状态,节点间可逆。 规定驱动工作流侧重于节点的运行规定,基于业务规定进行工作流程的执行,在解决具备明确指标但“规定”或标准级别不同的各种我的项目时,规定驱动的工作流十分有用。 能够看到不同类型的工作流不是齐全割裂的,状态机工作流中也能够联合着条件和规定进行操作节点转换的过程。在软件开发中,个别会思考联合状态机和规定驱动的工作流。 2.5 工作流引擎和状态机的差别在之前的文章外面,咱们有对状态机和工作流引擎做过一次简略的比照,事实上,两者之间并不是一个齐全对等的概念: 状态机是零碎状态以及这些状态之间转移和动作等行为的数学计算模型,而工作流是对整体工作流程及其各操作步骤之间业务逻辑和规定的形象建模。状态机模式是事件驱动型,大多通过内部事件触发状态的主动流转;工作流引擎更侧重于形容预约义流程工作实现之后的主动流转,可预测性会更强。从实用场景的复杂性上看,间接应用状态机的形式能够清晰地描绘出所有可能的状态以及导致转换的事件,实用于解决单维度、复杂度不高的业务问题,施展灵便轻便的特点;工作流引擎则更适宜简单的业务流程治理,解决如大型CRM复杂度更高的流程自动化问题,聚焦于改善整体业务流程的效率。工作流引擎是能够在状态机的构造模型根底上进行构建,事实上很多开源的工作流引擎也都是基于状态机的实现形式。理解了工作流的根本特点和应用场景之后,咱们来看一下比拟风行的开源工作流引擎。 三、开源工作流引擎 四、工作流引擎自研设计4.1 应用开源工作流引擎的问题开源工作流最大的劣势是能够借助开源的资源,开箱即用,性能全面,然而与之带来的是附带的配置和表数量比拟多的保护问题。以Activiti为例,应用Activiti7.0版本至多要引入二十多张表,尽管说看似是无侵入的形式,然而零碎演进和保护过程中有肯定的老本。特地是业务流程实例很多的时候,开发人员须要对表逻辑有更深的把控。因为业务的主观独特性,作为业务流程组件,个别都须要依据本身业务进行二次开发适配。 比方须要依据本身组织架构,进行流程节点用户角色权限的管控;将本身的业务能力插件化,退出工作流程配置中,进行拦挡回调等。4.2 自研引擎外围设计思路4.2.1 引擎外围模块回归工作流的实质, 工作流是通过预约义的流程模板,对事实流动进行实例化的过程。一个根本的工作流引擎次要包含三大外围局部: 流程模板创立依据业务规定和逻辑,创立流程模板,设置每一个节点的操作和变更门路。基于模板创立,能够延长出流程设计器、插件式节点,多样化的模板文件格式、模板长久化等。 流程实例公布依据流程模板,创立一个流程实例,流程模板和流程实例的关系相似类和对象的关系。比如说工单系统管理员定义好一个审批流模板(流程模板),用户点击创立一个工单(流程实例)。基于流程实例公布,又能够延长出实例实时观测,节点变迁记录回溯,实例状态长久化,失败重试,事务管制等。 工作流程执行创立好流程实例之后,流程实例只须要依照流程模板的定义独立执行各自实例的工作,不同的实例之间互不影响,实现各自实例的生命周期。 4.2.2 引擎外围设计① 利用容器启动时,加载流程引擎环境配置,包含解析器结构,流程引擎上下文,流程定义文件门路等。 ② 读取定好的流程定义文件,进行流程节点解析,构建好执行上下文,将流程节点放到内存缓存中。 ③ 业务侧进行流程创立,启动一个新的流程实例,同时将业务流程和流程实例进行绑定。 ④ 运行流程实例各个节点,将每个流程节点进行长久化保留。 4.3 具体实际① 引擎外围服务。 引擎操作的次要对外接口,包含启动流程实例,和获取相干流程定义模板,流程实例,流程节点的服务。 ...

July 19, 2022 · 2 min · jiezi

关于workflow:Apache-Dolphinscheduler300beta1-版本发布新增FlinkSQLZeppelin任务类型

导读:近日,Apache Dolphin Scheduler 迎来了 3.0.0-beta-1 版本的正式公布。新版本次要针对 3.0.0-alpha 进行了代码和文档的修复,并引入了局部的性能,如反对 FlinkSQL 工作类型,新增 Zeppelin 工作类型,新增 Kubernetes namespace 治理性能,以及通过 bash 传参性能等,具体更新详见下文。 01 新性能反对 FlinkSQL 工作类型在该版本中,咱们扩大了 Flink 工作类型,使其反对运行 Flink SQL 工作,其应用 sql-client.sh 提交工作。 更多详情查看: flink sql client](https://nightlies.apache.org/flink/flink-docs-master/docs/dev/table/sqlclient/) 对应 PR:9840 【链接】 https://github.com/apache/dolphinscheduler/pull/9840 新增 Zeppelin 工作类型在该版本中,咱们减少了 Zeppelin 工作类型,用于创立并执行 Zeppelin 类型工作。Worker 执行该工作时,会通过 Zeppelin Cient API 触发 Zeppelin Notebook 段落。 PR:9810 【链接】 https://github.com/apache/dolphinscheduler/pull/9810 新增 Kubernetes namespace 治理该版本新增了 kubernetes namespace 治理性能,容许用户在 Apache DolphinScheduler 中治理 Kubernetes 的 namespace。 ...

June 15, 2022 · 1 min · jiezi

关于workflow:金融任务实例实时离线跑批Apache-DolphinScheduler在新网银行的三大场景与五大优化

在新网银行,每天都有大量的工作实例产生,其中实时工作占据少数。为了更好地解决工作实例,新网银行在综合思考之后,抉择应用 Apache DolphinScheduler 来实现这项挑战。现在,新网银行多个我的项目曾经实现了实时与准实时的跑批,指标管理系统的离线跑批,利用于离线数据开发和任务调度、准实时数据开发和任务调度,以及其余非 ETL 用户定义数据跑批三类场景中。 为了更好地适应业务需要,新网银行是如何基于Apache DolphinScheduler 做革新的呢?在 Apache DolphinScheduler 4 月Meetup上,来自新网银行大数据中心的高级大数据工程师 陈卫,为咱们带来了《 Apache DolphinScheduler 在新网银行的实际利用》。 本次分享分为四个环节: 新网银行引入 Apache DolphinScheduler 的背景介绍Apache DolphinScheduler 的利用场景对新网银行的优化与革新新网银行应用 Apache DolphinScheduler 的后续打算 陈卫 新网银行 大数据中心 高级大数据工程师 11 年工作教训,晚期从事数据仓库建设,后转向大数据根底平台、调度零碎等建设,有传统金融行业、互联网数据仓库、数据集市建设教训,多年的调度零碎建设教训,咪咕文化剖析云调度零碎设计,报表平台设计,目前次要负责新网银行 DataOps 体系相干零碎建设(离线开发,指标零碎,标签零碎)。 01背景介绍咱们抉择应用 Apache DolphinScheduler 次要基于三大需要:研发场景的对立、测试场景的优化,以及投产部署场景优化。 01研发场景过来,咱们在数据开发过程中无对立的开发工具,因而新网银行在开发工作过程中,须要在多个工具间来回切换,导致过高的开发成本; 另一方面,咱们在开发过程中的参数替换需要无奈满足,无奈进行即席调试,无现成工具反对开发态与生产态离线工作。 02测试场景在测试场景的部署的过程中,当咱们的开发人员将脚本提供给测试,返回的文档却相当不敌对。尤其是须要在多个版本多个场景中部署的时候,测试人员的任务量骤增,可视化的部署也绝对较弱,无奈进行较敌对的自动化测试。 03投产部署以后调度系统配置简单,可视化成果差;开发与生产环境网络物理隔离,因而开发环境代码部署至生产环境流程长,易出错。测试环境无奈充分体现生产环境配置,手动配置文件易出错,易漏配;运维监控能力有余,可视化成果差,无奈在线查看日志,故障排除进入监控机房须登录物理机器,流程简单。02利用场景咱们利用 Apache DolphinScheduler 的场景次要有以下离线数据开发以及任务调度、准实时数据开发以及任务调度以及其余非 ETL 用户定义数据跑批三类。 01离线数据开发以及任务调度 在离线数据开发以及任务调度中,次要利用于咱们的银行业的数据仓库、数据集市等,数据包含一些离线数据,按日按月的离线加工的数据等。 02准实时数据开发以及任务调度 在新网银行中准实时的数据是通过 Flink 从上游的音讯队列数据库的日志外面进行交融计算,补全相干维度信息后,把数据推送到 Clickhouse 内进行解决。但按分钟级进行跑批计算,但绝对于日常的按日跑批的调度,会有一些非凡的需要。 03其余非ETL用户定义数据跑批 咱们有这部分的利用是通过一些外部的低代码平台来实现性能,咱们将利用零碎凋谢给业务人员,他们能够自助剖析利用数据,不须要开发人员解决。业务人员定义好后,能够自助对这部分数据进行跑批。 1、离线数据开发以及任务调度其中,咱们在离线数据开发和任务调度场景中利用 Apache DolphinScheduler ,次要波及工作开发调式、历史的工作集成、工作流与工作拆散、我的项目环境变量、数据源查找五个板块。 1、工作开发调式(SQL,SHELL,PYTHON,XSQL等),在线开发调式(在下查看日志,在线查看 SQL 查问返回后果)。WEBIDE 能够主动对弹窗变量替换,会依据用户的设置以及默认的解决进行动静替换。 2、历史的工作集成 银行业大部分数仓曾经建设了四五年,有很多的历史工作,因而,咱们不心愿咱们新的零碎上线的时候,用户须要自主革新代码,因为这样会导致用户的应用老本绝对过高。 3、工作流与工作拆散 开发间接开发工作并调式、测试,工作流间接援用已开发工作,这样咱们的工作开发与咱们的工作编排就进行了相应的切割。 ...

May 17, 2022 · 1 min · jiezi

关于workflow:又是一年开源之夏八大课题项目奖金等你来拿

又是一年【开源之夏】季。往年,Apache DolphinScheduler 同样参加到了【开源之夏】流动中来,心愿有更多学生群体关注到 Apache DolphinScheduler,并踊跃参加我的项目共建拿奖金! No.1 流动介绍开源之夏是由“开源软件供应链点亮打算”发动并长期反对的一项暑期开源流动,由中国科学院软件研究所与 openEuler 社区独特举办,旨在激励在校学生积极参与开源软件的开发保护,促成优良开源软件社区的蓬勃发展,造就和挖掘更多优良的开发者。 学生可自主抉择感兴趣的我的项目进行申请,并在当选后取得社区导师亲自领导。依据我的项目的难易水平和实现状况,参与者还将获取开源之夏流动奖金和结项证书。 开源之夏流动官网:https://summer.iscas.ac.cn/ No.2 流动日程 No.3 我的项目介绍Apache DolphinScheduler 是一个云原生易扩大的可视化 DAG 工作流任务调度零碎。致力于解决数据处理流程中简单的工作依赖关系,使各种工作类型(Spark /Flink/MR/Shell/Python/SQL等)在工作流编排中开箱即用。 No.4 奖金设置进阶:奖金人民币 12000 元优化类的工作,例如进步性能,升高资源占有根底:奖金人民币 8000 元性能类的工作,例如为本社区开源我的项目减少一个或若干个重要个性等No.5 八大课题本次流动,Apache DolphinScheduler 开源社区共设有 8 个我的项目课题具体如下,欢送参加: 01 为 DolphinScheduler Python API 增加资源文件【项目编号】222290294 【我的项目难度】进阶/Advanced 【编程语言】Python 【我的项目形容】目前,DolphinScheduler Python API 只能传递字符串格局传递工作的参数,例如咱们的 tutorial dolphinscheduler/dolphinscheduler-python/pydolphinscheduler/src/pydolphinscheduler/examples/tutorial.py 咱们只将一个字符串传递给shell工作类型。但通常来说,用户心愿具体的执行代码贮存在其余零碎中(心愿更好保护和集成),例如将具体文件存储在本地文件系统、GitHub、GitLab、Amazon S3、阿里云 OSS 等。兴许咱们能够增加语法糖让用户更加简略的操作内部文件 工作 task_parent 将从 URL https://github.com/apache/dolphinscheduler/blob/dev/script/install.sh 加载文件内容并将其传递给参数 command,它使咱们的 DAG 文件更容易和可保护 【我的项目产出要求】 实现 Resource 的插件化 实现具体的插件 Resource 包含但不限于本地文件系统,GitHub, GitLab, Amazon S3, 阿里云 OSS ...

May 13, 2022 · 2 min · jiezi

关于workflow:Apache-DolphinScheduler-2X保姆级源码解析中国移动工程师揭秘服务调度启动全流程

2022年1月,科学技术部高新技术司副司长梅建平在“第六届中国新金融高峰论坛”上示意,以后数据量曾经大大超过了解决能力的下限,若信息技术依然是渐进式倒退,则数据处理能力的晋升将远远落后于指数级增长的数据量。因而,在一段期间内,数据处理能力与效率的晋升仍将是大数据倒退要面对的技术难点。 随着5G、物联网等网络信息技术的疾速倒退以及利用的快速增长,数据量也呈指数级增长,纵观运营商整个大数据开发的链路上,在各个环节都会呈现各种严厉的问题,随着数据任务调度量级日益增大,妨碍数据正确且高效地施展价值,对运营商数据团队提出严厉挑战。 在大数据畛域,越来越多的企业拥抱开源软件,在这个背景下,咱们针对数据调度工具如何正确选型? 中国移动云能力核心软件开发工程师徐海辉示意:古语云“工欲善其事必先利其器”,如果你正处于张望/不知如何下手/行将参加开源我的项目的小伙伴,我倡议能够先从一个优良的开源社区源代码的动手,我在中国移动目前次要负责数据服务,这次在 Apache DolphinScheduler 4月 Meetup 上为大家带来DolphinScheduler源码2.X解析,心愿你有所播种。 本次演讲次要蕴含四个局部: 开篇与源码环境筹备服务启动流程工作执行流程集体思考与总结 徐海辉 中国移动云能力核心 软件开发工程师。从事大数据根底平台开发,次要负责中国移动Hadoop大数据平台组件Ranger 、挪动云Lake House 产品的研发 关键词:Apache DolphinScheduler源码2.X解析、源码环境筹备、服务启动、工作执行 Apache DolphinScheduler 源码下载链接: https://dolphinscheduler.apache.org/zh-cn/download/download.html 01 开篇与源码环境筹备Apache DolphinScheduler是一个基于java开发的开源分布式工作流调度零碎。致力于可视化操作工作及工作流之间的依赖关系,并可视化整个数据流过程;解决数据处理流程中盘根错节的依赖关系。 01 动手DolphinScheduler须要思考的问题开源分布式的工作原理?工具可视化是体现在哪里?Master和Worker之间如何通信?怎么体现工作流之间的依赖关系?“Show me the code” 其实在这个过程中须要思考的问题有很多,咱们无妨从官网给的架构图先简略梳理一下,而后通过理论的应用,再去钻研源码,一套组合拳下来就差不多了。 02 DolphinScheduler架构图话不多说,开撸! 4个由源码启动的服务是:UI、MasterServer、WorkServer、AlertServer(还有LoggerServer图外面没有体现) MasterServer & WorkServer依赖于Zookeeper协调服务中心注册MasterServer & WorkServer 1-N组成集群,别离是独自的服务和过程执行工作反对的插件:Flink、Shell、Subflow、SQL、Procedure、Python、MR、Spark、Dependent等等03 事后必备常识Netty一个异步的、基于事件驱动的网络应用框架,用于疾速开发可保护、高性能的网络服务器和客户端 Zookeeper一个分布式的,开放源码的分布式应用程序协调服务,它是一个为分布式应用提供一致性服务的软件,提供的性能包含:配置保护、域名服务、分布式同步、组服务等。 分布式锁为了解决单机部署状况下的并发管制锁策略生效这个问题,须要一种跨机器的互斥机制来管制共享资源的拜访 Quartz定时主动执行工作 多线程很多小伙伴不明确Master和Worker之间是怎么通信的,DolphinScheduler是基于Netty框架来实现的。这里能够拓展一下,服务器之间的通信还有很多形式: HTTPHTTP:http其实是一种网络传输协定,基于TCP,规定了数据传输的格局。 REST APIREST API通信是通过JSON格局的字符串进行数据传输的,而字符串是能够在网络中穿透防火墙的。也就是说,REST API能够穿透防火墙。同时字符串也能够不必受开发语言的限度,能够同时实现后端与WEB,后端与APP(Android,IOS)之间的通信。 RPCRPC通信又称近程过程调用,在内网中速度十分快,效率高。 如下图是筹备相干环境的部署,并且我还提供了一个近程Debug的形式,这个不难理解,比方你想调试API,在启动过程中,它必定会调用脚本,你只须要在脚本外面增加 Debug启动的一些参数,就能够进行一个近程的Debug。 像框框外面的数字实际上是服务的端口号,如果跟本地服务/其余组件端口之间有抵触的话,对它能够进行一个批改。 02 服务启动流程01 Master启动流程MasterServer采纳分布式无核心设计理念,基于Netty提供监听服务。MasterServer服务启动时向Zookeeper注册长期节点,通过监听Zookeeper长期节点变动来进行容错解决。MasterServer次要负责 DAG 工作切分、工作提交监控,并同时监听其它MasterServer和WorkerServer的衰弱状态。启动步骤 启动Netty 服务端服务注册到Zookeeper启动Event处理器启动scheduler定时工作启动StateWheel处理器↓↓↓源码一览↓↓↓ 对应门路外面寄存了MasterServer.java的类,外面有对应的main办法 执行完构造函数后,会启动run办法及其各个组件 这里会提前结构参数 调用start办法启动 注册元数据信息到Zookeeper下面,值得一提的是这里采纳的是长期门路,比如说在过程中服务断开了或者session过期,长期门路过一段时间会本人去Delete掉。 启动调度服务 ...

May 11, 2022 · 1 min · jiezi

关于workflow:中国联通改造-Apache-DolphinScheduler-资源中心实现计费环境跨集群调用与数据脚本一站式访问

截止2022年,中国联通用户规模达到4.6亿,占据了全中国人口的30%,随着5G的推广遍及,运营商IT零碎广泛面临着海量用户、海量话单、多样化业务、组网模式等一系列改革的冲击。 以后,联通每天解决话单量超过400亿条。在这样的体量根底上,进步服务水平,为客户提供更有针对性的服务,也成为了联通品牌谋求的终极目标。而中国联通在海量数据会集、加工、脱敏、加密等技术与利用方面已锋芒毕露,在行业中具备肯定的先发劣势,将来势必成为大数据赋能数字经济倒退的重要推动者。 在 Apache DolphinScheduler 4月 Meetup 上,咱们邀请到了联通软件研究院的柏雪松,他为咱们分享了《DolphinScheduler在联通计费环境中的利用》。 本次演讲次要包含三个局部: DolphinScheduler在联通的总体应用状况联通计费业务专题分享下一步的布局 柏雪松 联通软研院 大数据工程师 毕业于中国农业大学,从事于大数据平台构建和 AI 平台构建,为 Apache DolphinScheduler 奉献 Apache SeaTunnel(Incubating) 插件,并为 Apache SeaTunnel(Incubating) 共享 alluxio 插件 01  总体应用状况首先给大家阐明一下联通在DolphinScheduler的总体应用状况: 当初咱们的业务次要运行在3地4集群总体工作流数量大略在300左右日均工作运行差不多5000左右咱们应用到的DolphinScheduler组件包含Spark、Flink、SeaTunnel(原Waterdrop),以及存储过程中的Presto和一些Shell脚本,涵盖的业务则蕴含稽核,支出摊派,计费业务,还有其余一些须要自动化的业务等。 02 业务专题分享01 跨集群双活业务调用 上文说过,咱们的业务运行在3地4集群上,这样就免不了集群之间的相互的数据交换和业务调用。如何对立治理和调度这些跨集群的数据传输工作是一个重要的问题,咱们数据在生产集群,对于集群网络带宽非常敏感,必须有组织地对数据传输进行治理。 另一方面,咱们有一些业务须要跨集群去调用,例如A集群数据到位后B集群要启动统计工作等,咱们抉择 Apache DolphinScheduler作为调度和管制,来解决这两个问题。 首先阐明下咱们跨集群数据传输的流程在AB两个集群上进行,咱们均应用HDFS进行底层的数据存储,在跨集群的HDFS数据交换上,依据数据量大小和用处,咱们将应用的数据分为小批量和大批量数据,向构造表,配置表等。 对于小批量数据,咱们间接将其挂载到同一个Alluxio上进行数据共享,这样不会产生数据同步不及时导致的版本问题。 像明细表和其余大文件,咱们应用Distcp和Spark混合进行解决;对于构造表数据,应用SeaTunnel on Spark的形式;通过Yarn队列的形式进行限速设置;非构造数据应用Distcp传输,通过自带的参数Bandwidth进行速度限制;这些传输工作都是运行在DolphinScheduler平台下面,咱们整体的数据流程次要是A集群的数据到位检测,A集群的数据完整性校验,AB集群之间的数据传输,B集群的数据稽核和到位告诉。 强调一点:其中咱们重点用到了DolphinScheduler自带的补数重跑,对失败的工作或者不残缺的数据进行修复。 在实现了跨集群的数据同步和拜访,咱们还会应用DolphinScheduler进行跨地区和集群的工作调用。 咱们在A地有两个集群,别离是测试A1和生产A2,在B地有生产B1集群,咱们会在每个集群上拿出两台具备内网IP的机器作为接口机,通过在6台接口机上搭建DolphinScheduler建设一个虚构集群,从而能够在对立页面上操作三个集群的内容; Q:如何实现由测试到生产上线? A:在A1测试上进行工作开发,并且通过测试之后,间接将worker节点改变到A2生产上; Q:遇到A2生产出了问题,数据未到位等状况怎么办? A:咱们能够间接切换到B1生产上,实现手动的双活容灾切换; 最初咱们还有些工作比拟大,为满足工作时效性,须要利用两个集群同时计算,咱们会将数据拆分两份别离放到A2和B1下面,之后同时运行工作,最初将运行后果传回同一集群进行合并,这些工作流程根本都是通过DolphinScheduler来进行调用的。 请大家留神,在这个过程中,咱们应用DolphinScheduler解决了几个问题: 我的项目跨集群的工作依赖校验;管制节点级别的工作环境变量;02 AI开发同步工作运行 1、对立数据拜访形式 咱们当初曾经有一个繁难的AI开发平台,次要为用户提供一些Tensorflow和Spark ML的计算环境。在业务需要下,咱们须要将用户训练的本地文件模型和集群文件系统买通,并且可能提供对立的拜访形式和部署办法,为解决这个问题,咱们应用了Alluxio-fuse和DolphinScheduler这两个工具。 Alluxio-fuse买通本地和集群存储DolphinScheduler共享本地和集群存储因为咱们搭建的AI平台集群和数据集群是两个数据集群,所以在数据集群上咱们进行一个数据的存储,利用Spark SQL或者Hive进行一些数据的预加工解决,之后咱们将解决完的数据挂载到Alluxio上,最初通过Alluxio fuse跨级群映射到本地文件,这样咱们基于Conda的开发环境,就能够间接拜访这些数据,这样就能够做到对立数据的拜访形式,以拜访本地数据的办法拜访集群的数据。 2、数据脚本一站式拜访 拆散资源之后,通过预处理大数据内容通过数据集群,通过咱们的AI集群去解决训练模型和预测模型,在这里,咱们应用Alluxio-fuse对DolphinScheduler的资源核心进行了二次改变,咱们将DolphinScheduler资源核心连贯到Alluxio上,再通过Alluxio-fuse同时挂载本地文件和集群文件,这样在DolphinSchedule下面就能够同时拜访在本地的训练推理脚本,又能够拜访到存储在hdfs上的训练推理数据,实现数据脚本一站式拜访。 03 业务查问逻辑长久化 第三个场景是咱们用Presto和Hue为用户提供了一个前台的即时查问界面,因为有些用户通过前台写完SQL,并且测试实现之后,须要定时运行一些加工逻辑和存储过程,所以这就须要买通从前台SQL到后盾定时运行工作的流程。 ...

May 7, 2022 · 1 min · jiezi

关于workflow:百亿级数据同步如何基于-SeaTunnel-的-ClickHouse-实现

作者 | Apache SeaTunnel(Incubating) Contributor 范佳 整顿 | 测试工程师 冯秀兰 对于百亿级批数据的导入,传统的 JDBC 形式在一些海量数据同步场景下的体现并不尽如人意。为了提供更快的写入速度,Apache SeaTunnel(Incubating) 在刚刚公布的 2.1.1 版本中提供了 ClickhouseFile-Connector 的反对,以实现 Bulk load 数据写入。 Bulk load 指把海量数据同步到指标 DB 中,目前 SeaTunnel 已实现数据同步到 ClickHouse 中。 在 Apache SeaTunnel(Incubating) 4 月 Meetup 上,Apache SeaTunnel(Incubating) Contributor 范佳分享了《基于 SeaTunnel 的 ClickHouse bulk load 实现》,具体解说了 ClickHouseFile 高效解决海量数据的具体实现原理和流程。 感激本文整顿志愿者 测试工程师 冯秀兰 对 Apache SeaTunnel(Incubating) 我的项目的反对! 本次演讲次要蕴含七个局部: ClickHouse Sink 现状ClickHouse Sink 弱场景ClickHouseFile 插件介绍ClickHouseFile 核心技术点ClickHouseFile 插件的实现解析插件能力比照前期优化方向 范 佳白鲸开源 高级工程师 ...

May 6, 2022 · 2 min · jiezi

关于workflow:300-alpha-重磅发布九大新功能全新-UI-解锁调度系统新能力

2022 年 4 月 22 日,Apache DolphinScheduler 正式发表 3.0.0 alpha 版本公布!此次版本升级迎来了自发版以来的最大变动,泛滥全新性能和个性为用户带来新的体验和价值。3.0.0-alpha 的关键字,总结起来是 “更快、更现代化、更强、更易保护”。 更快、更现代化:重构了 UI 界面,新 UI 不仅用户响应速度进步数十倍,开发者构建速度也进步数百倍,且页面布局、图标款式都更加现代化; 更强:带来了许多振奋人心的新性能,如数据品质评估、自定义时区、反对 AWS,并新增多个工作插件和多个告警插件; 更易保护:后端服务拆分更加合乎容器化和微服务化的发展趋势,还能明确各个服务的职责,让保护更加简略。 新性能和新个性01 全新 UI,前端代码更强壮,速度更快3.0.0-alpha 最大的变动是引入了新的 UI,切换语言页面无需从新加载,并且新增了深色主题。新 UI 应用了 Vue3、TSX、Vite 相干技术栈。比照旧版 UI,新 UI 不仅更加现代化,操作也更加人性化,前端的鲁棒性也更强,使用户在编译时一旦发现代码中的问题,能够对接口参数进行校验,从而使前端代码更加强壮。 此外,新架构和新技术栈不仅能让用户在操作 Apache DolphinScheduler 时响应速度有数十倍的晋升,同时开发者本地编译和启动 UI 的速度有了数百倍的晋升,这将大大缩短开发者调试和打包代码所需的工夫。新 UI 应用体验: 本地启动耗时比照 首页 工作流实例页面 Shell 工作页面 MySQL 数据源页面 02 反对 AWS随着 Apache DolphinScheduler 用户群体越来越丰盛,吸引了很多海内用户。但在海内业务场景下,用户在调研过程中发现有两个影响用户便捷体验 Apache DolphinScheduler 的点,一个是时区问题,另一个则是对海内云厂商,尤其是对 AWS 的反对有余。为此,咱们决定对AWS 较为重要的组件进行反对,这也是此版本的最重大的变动之一。 目前,Apache DolphinScheduler 对 AWS 的反对曾经涵盖 Amazon EMR 和 Amazon Redshift 两个 AWS 的工作类型,并实现了资源核心反对 Amazon S3 存储。 ...

April 25, 2022 · 3 min · jiezi

关于workflow:一个逻辑完备的线程池

一个逻辑齐备的线程池开源我的项目Workflow中有一个十分重要的根底模块:代码仅300行的C语言线程池。 逻辑齐备的三个特点在第3局部开始解说,欢送跳阅,或间接到Github主页上围观代码。 https://github.com/sogou/work... 0 - Workflow的thrdpoolWorkflow的大招:计算通信融为一体的异步调度模式,而计算的外围:Executor调度器,就是基于这个线程池实现的。能够说,一个通用而高效的线程池,是咱们写C/C++代码时离不开的根底模块。 thrdpool代码地位在src/kernel/,不仅能够间接拿来应用,同时也适宜浏览学习。 而更重要的,秉承Workflow我的项目自身一贯的谨严极简的风格,这个thrdpool代码极致简洁,实现逻辑上亦十分齐备,构造精美,处处谨严,不得不让我惊叹: 妙啊!!! 你可能会很好奇,线程池还能写出什么别致的新思路吗?先列出一些,你们细品: 特点1:创立完线程池后,无需记录任何线程id或对象,线程池能够通过一个等一个的形式优雅地去完结所有线程;特点2:线程工作能够由另一个线程工作调起;甚至线程池正在被销毁时也能够提交下一个工作;(这很重要,因为线程自身很可能是不晓得线程池的状态的;特点3:同理,线程工作也能够销毁这个线程池;(十分残缺~我真的急不可待为大家深层解读一下,这个我愿称之为“逻辑齐备”的线程池。 1 - 前置常识第一局部我先从最根本的内容梳理一些集体了解,有根底的小伙伴能够间接跳过。如果有不精确的中央,欢送大家斧正交换~ 为什么须要线程池?(其实思路不仅对线程池,对任何无限资源的调度治理都是相似的) 咱们晓得,通过零碎提供的pthread或者std::thread创立线程,就能够实现多线程并发执行咱们的代码。 然而CPU的核数是固定的,所以真正并发执行的最大值也是固定的,过多的线程创立除了频繁产生创立的overhead以外,还会导致对系统资源进行争抢,这些都是不必要的节约。 因而咱们能够治理无限个线程,循环且正当地利用它们。♻️ 那么线程池个别蕴含哪些内容呢? 首先是治理若干个~工具人~线程;其次是治理交给线程去执行的工作,这个个别会有一个队列;再而后线程之间须要一些同步机制,比方mutex、condition等;最初就是各线程池实现上本身须要的其余内容了;好了,接下来咱们看看Workflow的thrdpool是怎么做的。 2 - 代码概览以下共7步罕用思路,足以让咱们把代码飞快过一遍。 第1步:先看头文件,模块提供什么接口。咱们关上thrdpool.h,能够只关注三个接口: // 创立线程池thrdpool_t *thrdpool_create(size_t nthreads, size_t stacksize);// 把工作交给线程池的入口int thrdpool_schedule(const struct thrdpool_task *task, thrdpool_t *pool); // 销毁线程池void thrdpool_destroy(void (*pending)(const struct thrdpool_task *),                      thrdpool_t *pool);第2步:接口上有什么数据结构。也就是,咱们如何形容一个交给线程池的工作。 struct thrdpool_task                                                            {                                                                                   void (*routine)(void *); // 一个函数指针    void *context; // 一个上下文};  第3步:再看实现.c,有什么外部数据结构。struct __thrdpool{    struct list_head task_queue;   // 工作队列    size_t nthreads;               // 线程个数    size_t stacksize;              // 结构线程时的参数    pthread_t tid;                // 运行起来之后,pool上记录的这个是zero值    pthread_mutex_t mutex;    pthread_cond_t cond;    pthread_key_t key;    pthread_cond_t *terminate;};没有一个多余,每一个成员都很到位: ...

April 23, 2022 · 6 min · jiezi

关于workflow:数据分析师干了专业数仓工程师的活自如是怎么做到的

数据分析师作为企业数据资产的缔造者之一,具备肯定的维度与指标体系治理、血统剖析、ETL 调度平台等技能。可能灵便应用调度平台会为数据分析师带来很大的便当,然而对于编程技能程度参差不齐的数据分析师来说,一个操作简略,应用成本低的调度平台能力让他们锦上添花,而不是减少额定的学习老本。 与大多企业相比,自若大数据平台的独特之处在于,大量的数仓加工并非由业余的数仓工程师实现,而是由数据分析师所做。而自若的数据分析师之所以可能做到业余团队能力实现的简单的数据处理、剖析工作,与其调度零碎迁徙到 Apache DolphinScheduler 分不开。 在不久前的 Apache DolphinScheduler& Apache ShenYu(Incubating) Meetup 上,自若大数据研发经理 刘涛,为咱们分享了受数据分析师们欢送的调度零碎是什么样的。 刘涛自若大数据研发经理,负责自若大数据根底平台构建,建设一站式大数据开发平台。 01 自若大数据平台现状 自若大数据平台上图是自若大数据离线平台的简略图示,数据源包含 MySQL、Oracle 等业务库数据,以及各种日志数据,通过 Hive 离线 T 加 1 采集、另外应用Hive acid加上Flink实现了一个10分钟级别的业务库数据更新。 数据加工是分析师关怀的局部,这个过程能够配置调度、配置依赖和 SQL 开发。而在数据落地上,咱们采纳了 ClickHouse 的 OLAP 引擎,数据应用层应用网易无数提供报表平台。 自若的大数据平台与业界大多数平台相差不大,但独特之处在于除了反对业余数仓开发工程师外,大量的数据分析师参加到了数仓加工之中。这就要求大数据平台要足够简化。 02 分析师的冀望 因为数据分析师的编码程度参差不齐,有些分析师会写 SQL,而有些分析师基本不会写 SQL。即便是对于会写 SQL 的分析师,在面对工作依赖概念的了解上,也会感觉难度很大。 因而,分析师群体对于调度的冀望是要简略,上手成本低。 03 Airflow的实现形式 一开始,自若选用的是 Airflow,应用Airflow 可视化插件Airflow DAG createmanager plug-in来供分析师用,底层应用hivepartitionsensor,用数据依赖的形式配置调度,便于分析师了解和应用,这套解决方案,对于分析师来说体验尚可,然而面临几个较大的问题: 数据依赖的底层实现导致的工作重跑非常复杂; 任务量比拟多后,调度性能较差,有些工作调起提早较大; 与一站式大数据开发平台集成二开老本比拟高; 原生不反对多租户。 04 Apache DolphinScheduler革新与 Airflow工作迁徙 以上几个比拟重要的挑战,促使咱们从新进行调度选型。通过比照剖析后,咱们抉择了 Apache DolphinScheduler。 对于分析师来说,数据依赖是一个好了解的概念,但工作依赖就比拟让人费解。 比拟现实的计划是对分析师展现的是数据依赖,底层实现是工作依赖,并且这数据依赖是自动生产的,不须要分析师手动输出依赖表。 做到这一点,首先须要解决一个问题,如何依据一段 SQL,判断出这段 SQL 的输入输出表? ...

April 6, 2022 · 1 min · jiezi

关于workflow:极速开发扩充-Apache-DolphinScheduler-Task-类型-实用教程

背景简介目前在大数据生态中,调度零碎是不可或缺的一个重要组件。Apache DolphinScheduler 作为一个顶级的Apache 我的项目,其稳定性和易用性也能够说是名落孙山的。而对于一个调度零碎来说,可能反对的可调度的工作类型同样是一个十分重要的因素,在调度、分布式、高可用、易用性解决了的状况下,随着业务的倒退或者各种需要应用到的组件增多,用户自然而然会心愿可能疾速、不便、简洁地对 Apache Dolphinscheduler 可调度的工作类型进行裁减。本文便带大家理解如何不便、极速裁减一个 Apache DolphinScheduler Task。 作者简介张柏强,大数据开发工程师,次要钻研方向为实时计算、元数据治理、大数据根底组件。 01 什么是 SPI 服务发现(What is SPI)?SPI 全称为 (Service Provider Interface) ,是 JDK 内置的一种服务提供发现机制。大多数人可能会很少用到它,因为它的定位次要是面向开发厂商的,在 java.util.ServiceLoader 的文档里有比拟具体的介绍,其形象的概念是指动静加载某个服务实现。 02 为什么要引入 SPI(Why did we introduce SPI)?不同的企业可能会有本人的组件须要通过 task 去执行,大数据生态中最为罕用数仓工具 Apache Hive 来举例,不同的企业应用 Hive 办法各有不同。有的企业通过 HiveServer2 执行工作,有的企业应用 HiveClient 执行工作,而 Apache DolphinScheduler 提供的开箱即用的 Task 中并没有反对 HiveClient 的 Task,所以大部分使用者都会通过 Shell 去执行。然而,Shell 哪有人造的TaskTemplate 好用呢?所以,Apache DolphinScheduler 为了使用户可能更好地依据企业需要定制不同的 Task,便反对了 TaskSPI 化。 咱们首先要理解一下 Apache DolphinScheduler 的 Task 改版历程,在 DS 1.3.x 时,裁减一个 Task 须要从新编译整个 Apache DolphinScheduler,耦合重大,所以在 Apache DolphinScheduler 2.0.x 引入了 SPI。后面咱们提到了 SPI 的抽象概念是动静加载某个服务的实现,这里咱们具象一点,将 Apache DolphinScheduler 的 Task 看成一个执行服务,而咱们须要依据使用者的抉择去执行不同的服务,如果没有的服务,则须要咱们本人裁减,相比于 1.3.x 咱们只须要实现咱们的 Task 具体实现逻辑,而后恪守 SPI 的规定,编译成 Jar 并上传到指定目录,即可应用咱们本人编写的 Task。 ...

March 30, 2022 · 4 min · jiezi

关于workflow:C-Workflow异步调度框架-性能优化上篇

最近在致力同步保护SegmentFault的文章积攒~不便后续继续更新~ 原文是2019年7月底开源后陆续po的,这里对近况进行了调整和补充。 心愿本人和我的项目都能够继续提高 (╹ヮ╹)ノ 欢送多多交换!!搜狗C++ workflow异步调度框架github地址:GitHub - sogou/workflow: C++ Parallel Computing and Asynchronous Networking Engine 先来和大家update一下,这一周以来workflow又有哪些成长呢: 新版更简洁的README.mdserver默认应用ipv4启动(为了兼容windows与unix的行为加了全局配置项的文档about-config.md (正好和明天的话题相干!开源了两周,备受小伙伴们关注,真的很开心 >_< 特别感谢各位关注和反对咱们的大神们小朋友们,心愿可能继续和大家交换,一起提高~ (下图更新于2022年3月,开源一年多留个留念~) 我也在整顿开源我的项目规范化相干的事件,如果有哪里做得不到位,心愿能帮我指出~ 明天这个话题是十分通用的入门话题:写完代码咱们须要做什么最根本的零碎性能优化。 因为workflow是个异步调度引擎,workflow的职责就是让零碎各资源尽可能地利用起来,所以我的日常工作,除了写bug之外,还要配合开发小伙伴现场debug、剖析用了workflow之后的各项指标是否还能进一步晋升。 我还是联合具体几类资源为线索来介绍: CPU:多路复用相干的线程数、计算相干线程数、多过程网络:长连贯短连贯、连接数管制、超时配置、压缩计时器:timerfd的优化计数器:命名计数器与匿名计数器文件IO:理论场景用得少,先不写了GPU:目前我只做了demo版,所以没有放进去,也先不写了其中计时器和计数器绝对简略一些,我会这里介绍下外部实现,其余的外部实现做了很多优化,每个话题都值得当前独自写一下。 一、CPU先来看看咱们的配置项: static constexpr struct WFGlobalSettings GLOBAL_SETTINGS_DEFAULT ={ .endpoint_params = ENDPOINT_PARAMS_DEFAULT, .dns_ttl_default = 12 * 3600, .dns_ttl_min = 180, .dns_threads = 4, .poller_threads = 4, .handler_threads = 20, .compute_threads = -1,};1. 根本网络线程个别用epoll的框架都须要对其进行相似proactor式的封装,那么就要负责做以下事件,以及决定具体哪个线程去分工: 对epoll具体某个fd进行读写读写时把残缺数据包切下来数据包切完之后的解析(即反序列化)执行用户的操作Workflow以后的做法,poller_threads线程是去操作epoll读写和做fd读的切音讯的事件,而handler_threads是做根本用户操作的,比方callback和作为server的话,咱们的process函数所在的线程。 brpc是不须要辨别的,我集体了解有几个起因,比方: 它套了一层bthread做换线程的调度;fd上拉了写链表:没人在写你就写,有人在写你就把数据扔下就行了,这个人会帮你写,不存在相似handler线程还要回去管poller线程的异步写的事件;Workflow没有做这样的优化,次要还是因为一个过程内网络读写和业务操作压力比例根本是差不多确定的,业务上线前的调优调整一下poller和handler线程比例根本足够了,而且纯探讨性能的话,业内的解决方案根本是纯异步会比用户态协程模式快一点点,目前C++20的coroutine曾经进去了,心愿后续能更多业界成熟且高效的用法~Workflow目前才1岁多,很多优化可能都会往后放。 这里也顺带说一句,对于把数据包切下来和切完之后的解析,其实有些协定是不太能分得开的。 我鶸鶸地给大家列一下,从协定设计上,能够分以下三类: 收到音讯就能晓得我怎么残缺地切一条音讯进去;收一点之后判断一下能力晓得我怎么切一条音讯进去;一边收数据流一边解析,不到最初一刻都不晓得是不是收完。第1种就很简略,个别做RPC协定咱们都会敌对地在头部通知你大略多长。 第2种有点相似HTTP这样,大略收完头部你就晓得后边还有多少了,这个时候你收header,是要本人边收边parse的。 第3种比方MySQL这种吐血的协定,大略它在设计的时候就没有想过你要多线程去操作一个fd读音讯,你得依据以后哪种包的状态再判断,这种必须写个状态机去残缺收完了能力交给用户。而这个收的期间,我曾经把每个field和每个ResultSet给解析进去了,收完根本等于数据反序列化也做完了。所以第2种、第3种,对于切残缺音讯和解析音讯的反序列化操作其实并不会太分得开,workflow都会在poller_threads里做。 2. 计算线程咱们外部会有独立的计算线程池,默认是和零碎cpu数统一的数量,这个是根本能够缩小线程数过多而频繁切换的问题,当然如果用不到计算工作,此线程池不会创立。 和cpu数统一,那么不同期间不同类型的计算工作占比不同,这个workflow怎么解决呢?咱们外部用了一个谢爷创造的多维队列调度模型,曾经申请专利,当前有机会让谢爷写一篇给大家讲讲>_< ...

March 27, 2022 · 1 min · jiezi