当前位置: 首页 > 网络应用技术

PingCode流技术架构揭示了

时间:2023-03-07 02:27:52 网络应用技术

  作者:pingcode开发VP@作子

  本文是PingCode Flow系列的第四篇文章。如果这不足为奇,那也是最后一篇文章。从去年5月的pingcode流的正式发布中,我想到了四个文件的订单和一般内容。从引入当前状态,疼痛点和研发自动化的解决方案到展示如何使用pingcode流以实现R&D的自动化。而最后一篇文章是显示如何从纯技术中的PingCode流中工作观点,以及如何在每天近4,000条规则的压力下确保99%的规则。设备,并行,判断,周期和其他复杂的操作逻辑。

  同时,我们还希望在本文中分享我们如何分析和思考,并最终出现在结构中。因此,本文不会直接显示最终设计结果,但会解释为什么我们应该设计这样的设计,权衡优势和缺点,以及开发过程中的重建。

  Pingcode流量系列文章传送门

  在上一篇文章中,我们提到pingcode流是R&D的自动化工具。SO所谓的自动化意味着根据某个事件后根据预定义的过程完成一系列操作。因此,本质上,Pingcode流是一个点击(触发操作平台)系统。它由触发器和多个操作组成,以形成有序的执行规则,然后按照此规则顺序执行它。

  因此,当在技术体系结构中设计PingCode流时,有必要确保这样的过程可以平稳运行。

  在确定了产品的核心目标之后,首先是澄清如何定义数据。根据上述图标,用户可以在团队中定义多个规则,并且每个规则都包含一个触发器和多个后续操作。简单的需求,规则的数据结构可以定义如下。

  这样,规则包含触发器及其包含的操作。操作的序列号决定了其执行顺序。此设计似乎基本上满足了当前的产品需求。

  但是我们知道,当前的pingcode流不仅支持上述单行订单执行过程,而且还支持负责任的执行过程,例如条件,并行,判断和周期。工艺可以自由地,例如在平行线中的判断,判断中存在一个周期,并且在周期中存在相似之处……通过如此几乎无限的组合,可以实现几乎是任意的规则。

  因此,以上简单的数据结构无法完全满足需求。如何设计可以支持各种方案的规则是我们PingCode Flow团队面前的第一个问题。

  如果我们考虑“一系列动作规则”的方法,则很难设计一个相对通用的数据结构。因为规则中的操作由用户确定,因此不可能淘汰可能的结构。,您可以尝试考虑更改中的这个问题,也就是说,我们不再将规则视为触发器和动作的有序列表,而是将它们定义为链接列表。

  收藏。

  如果我们将“触发”和“动作”结合到“步骤”中。然后,规则是

  这样,我们对规则和步骤的定义可以统一

  也就是说,规则不在乎其内部行动是什么和秩序的顺序。它只关心第一个动作是什么。每个动作只关心下一个动作。

  对于平行,周期和判断等复杂过程,我们只需要扩展相应的数据结构即可实现不同的布置组合。例如,对于并行,其数据结构就是这样。

  “并行”中每个分支的第一步ID保存在数组中,指示要执行分支的第一步。“并行”本身并不关心每个分支中的特定过程。关心所有分支执行时的下一步是什么。

  基于此结构,对于上述复杂规则

  我们的数据大致像这样。因为,它仅设置下一步。

  为此,内部有两个分支,下一步由整个分支完成。因此,其数据就是这样。

  因为这是一个周期步骤。进入周期的第一步是它将在完成周期后结束当前分支操作。因此,其数据就是这样。

  对于空,这意味着当前分支已经结束。

  当我们确定数据结构时,还可以确定规则中的步骤的执行。类似于结构,当启动规则时(我们不考虑如何触发规则),它将首先找到第一个的ID熟悉pingcode流的阅读器知道,我们已经在系统中预设了许多动作,例如设置工作项目,创建页面,更改测试案例状态等等。因此如何执行这些操作。

  首先,每个操作都将具有一个全局唯一的名称。当规则执行到此步骤时,我们将通过步骤的ID找到其操作名称。位置在名称定位代码中的实际执行逻辑。

  例如,“设置工作项目”的动作,其连接器的名称是,操作名称为。代码大致如下。

  代码段

  主要代码是执行此步骤时将调用它。执行操作时,将返回数据库的返回,并且规则执行引擎将调用后续步骤。这是最简单的操作步骤,由系统调用,执行特定操作,然后返回下一步的ID。

  除了普通动作外,pingcode流还支持复杂的过程控制,例如条件,并行,判断和周期。在判断为真实时,请继续以下步骤,并停止当前的false步骤。然后是这样。

  代码段

  我们定义了一种抽象方法来实现衍生物的特定判断逻辑。如果结果是,它将返回,表明没有后续步骤,执行过程已经结束。

  至于“判断”,“并行”,“循环”的类型,它可能包含一个非常复杂的过程。也可以通过现有的数据结构和执行过程将其解耦,因此每个步骤仅需要在您自己的工作中需要构成范围。

  以“并行”为例,我们知道其数据结构包含

  因此,“并行”步骤的执行逻辑是在同一时间启动每个分支的第一步。然后等待所有分支的操作结束,然后返回下一步的ID。

  请注意,在该方法中,我们将数据库中定义的分支ID数组转换为异步操作executor.create()。执行并让他们在各自的上下文中执行。每个分支中的执行逻辑都如下。当规则被执行到分支中时,他们将不会意识到它们处于“并行”“分支”中。

  刚才我们介绍了如何保留数据和步骤,以及如何执行规则中的步骤。但是如何触发规则?目前,PingCode Flow支持三个规则:自动化,手动和即时时间。同时,自动化规则可以分为三个起始场景,如下所示:

  从上图可以看出,对于规则,它不需要关心它的触发方式。只需要知道在某个时间,有一个规则需要执行。,我们分别为此执行规则分开了一个模块,即“流动引擎”。它的责任很简单,即“启动一定规则”。

  对于负责收到接收规则请求的模块,它们具有普遍的责任,即根据其需求通知流动引擎以启动规则。上图中的五个触发规则,它们各自的职责如下:

  通过这种分裂,可以完全隔离规则和规则的触发器。在Pingcode流量开发的早期,我们仅支持从PingCode触发的规则,从PingCode.S.产品功能,我们连续意识到第三党产品(GitHub,Gitlab,Jenkins等),即时规则(手动触发)和正时规则(定时触发器)的访问权限。这些新触发方法并不影响其他模块,因此,它们确保产品的质量达到最大值。

  企业SaaS产品的核心需求是数据的安全性和服务的稳定性。一方面,我们的输出质量(即,代码)很高,另一方需要我们的服务来支持水平系统绩效问题和稳定性问题的扩展。单个责任模块的划分使我们在设计PingCode流量部署方法时具有更好的选择,更容易实现稳定性。

  具体而言,先前引入的执行模块(流动引擎)的五个接收模块和规则,其业务的业务逻辑不是状态,因此它可以支持独立的水平扩展。

  上图中的箭头表明每个触发模块启动了调用关系,并且按需激活流动引擎规则。我们最初是设计为基本框架的RPC函数。例如,如果用户修改工作项的状态,则触发模块“ pingcode sub -productuct”将通过RPC(HTTP或TCP请求)同步调用流动引擎接口,以启动相应的规则。

  但是pingcode流与其他pingcode sub -productss.pisode Flow的执行频率和实现时间基于客户定义规则。PingCode系统和各种外部系统中请求的操作和事件量和执行的操作和执行非常大。因此,需要在后端流动引擎上具有足够的弹性,这可以平稳地执行每个规则并在短时间内进行了大量操作。因此,在建筑审查会议上,最终直接拒绝了使用RPC的计划。

  由于体系结构目标是需要PingCode Flow系统才能在高峰期保护后端引擎模块,因此我们决定使用呼叫层和实际执行层之间的消息队列。

  通过消息队列,所有规则的执行请求将添加到队列中,然后读取和处理多个听力队列的流动引擎实例。这是,首先,一旦短期执行太大,执行请求将在消息队列中进行缓冲,而不会影响流动引擎。第二,呼叫者和执行者通过数据完全交互,两者在两者之间完全解耦。在操作卷波动时,我们可以连接新的流动引擎访问消息队列以完成扩展,而无需其他配置IP,端口号,请求转发和负载平衡。

  最后,下面显示了我们的pingcode流的整体体系结构。

  在与Pingcode的客户沟通时,经常被问到的问题是研发团队如何绘制一个良好的建筑设计?它不仅满足了未来扩展的需求,同时避免了过度的设计。在这方面,我的个人观点是世界上没有这样的良好设计,只有合理的设计。合理的设计不是来自建筑师的想象,而是根据现有的业务需求和可预见的场景逐渐发现的。

  尤其是在敏捷开发的大型场景中,每次迭代都是要完成一个可以反映客户价值的用户故事。因此,建筑设计不是在一夜之间实现,而是在每次迭代中不断思考,设计,练习,反馈和修改,并且终于获得了目前最合理的答案。

  原始:https://juejin.cn/post/7094480589390086157