基于状态机的流程编排架构设计

news2024/11/16 7:39:41

背景

  • xx产品侧规划了全新的能力升级, 主要思路为:改变之前通过xx等手工生成xx的方式,通过标准化流程尽可能的减少人工介入,提升产出效率。
  • xx入库、xx生成链路存在链路长、链路不稳定问题,由于目前缺乏比较好的监控、检测、补偿机制,导致链路中断后无法实时感知且无法及时介入推进,对用户体验有一定的影响。
  • 当前架构多是通过hard code的方式支撑各渠道的接入,存在代码耦合度高、难以扩展、难以修改的问题。代码质量因开发同学能力差异参差不齐。缺少统一的架构规约对编码进行约束。
    目标
    业务目标:
  • 支撑xx产品规划的业务能力建设。
    架构目标:
  • 通过灵活的链路编排,实现链路节点的复用和差异化处理,降低新渠道的接入成本。
  • 支持未来对单个链路任意数量的链路节点的灵活扩展。
  • 提供故障感知、链路推进的能力,达到对链路的精准感知和管控。
  • 架构规约,通过架构规范(扩展子类、新增配置)开闭原则来限制开发同学的修改、扩展,一定程度的提升编码质量
    设计思路
  • 事件驱动,所有请求均转化为事件,所有动作均由事件触发,事件与执行解耦。统一分发、处理。
  • 事件、状态、动作解耦,多维度灵活组合。
  • 基于状态机的流程编排及控制各节点精确流转。
  • 基于状态机的故障感知、数据补偿及流程推进。
    术语
  • 客户订单:客户需求的承载实体。
  • 标准化订单:通过标准化字段对原始客户订单归一化之后的订单实体。
  • 任务:全称为:标准化订单任务,基于标准化订单发起的xx制作任务。
  • xx策略:指出具体的制作方向。是对标准化订单的细化。创意策略系统的产出物。
  • 脚本xx:根据xx策略,让算法自动生成、拼接行程的xx部分。是xx系统的产出物。
  • 补偿注册:通知补偿模块将当前逻辑语句块(方法等)纳入到补偿管控范围。纳入管控范围后,将会对被注册模块周期性的执行检测、或者补偿。
  • 故障感知:检测到链路出现故障并上报。不同场景、节点的检测逻辑不同,因此需要不同的检测策略。
  • 补偿策略:检测到链路因为各种问题不推进时需要执行的逻辑。根据场景、错误具体原因不同,可以执行的补偿策略如重试、兜底查询、告警等各不相同。前期先至少可以做到告警,后根据具体原因和场景配置不同的策略。
  • 状态机:一种对状态流转进行管理的机制。整个状态机由多个状态组成,状态之间流转称为状态迁移。状态迁移由事件触发。
  • 状态机-源状态:状态机当前所处的状态。
  • 状态机-目标状态:状态机准备迁移的下一个状态
  • 状态机-动作:发生状态迁移后执行的动作。
  • Event: 事件,领域事件,可以认为是推进状态机发生状态迁移的触发源。根据具体场景不同,可以定义自己的Event。
  • EventDispatcher: 事件分发中心,可以认为是事件中转站,根据事件类型不同会分发到不同的目的地。整个系统采用事件驱动,统一由EventDispatcher分发,不允许上层直接驱动状态机。
  • EventRouter:维护事件和目的的路由关系,用于事件分发。本系统为维护event和所属状态机的路由关系。

xx状态机

策略任务维度状态机
生成任务维度状态机
在这里插入图片描述

应用架构

xx1.0位于xx-xx应用内,xx-xx后续定位为后台运营服务,1.0逻辑在2.0上线后逐步废弃。
xx2.0运行时服务,xx-xx-core,为新建应用。承载标准化订单、合成任务等。
逻辑架构
xx2.0运行时服务(新建)

领域模型

整体交互图
创建订单场景

收到算法投递的xx成功&失败事件&补偿xx失败逻辑

关键类
在这里插入图片描述

子系统改造
各子系统设计方案见子目录对应模块设计文档。

状态机使用
增加新的节点(如在两个状态state1和state2间增加审批节点,且审批通过后通知用户):

  • StateType枚举增加:待审批-approving、已审批-approved、审批拒绝-approveRefuesed。
  • EventType枚举增加:审批通过事件-approvedEvent、审批拒绝事件-approveRefuesedEvent。
  • 创建ApprovedNotifySlot,并实现execute方法。用于审批通过后通知用户。
    public class ApprovedNotifyActionSlot implement StateAction {
    public onDo(State from, State to, Event event) {
    // 通知到用户逻辑
    }
    }
  • StateTransitBuilder配置该状态的迁移路由(谁迁移到它,它迁移到哪)

StateTransiBuilder builder = StateTransiBuilderFactory.create();
builder.create()
.from(state1)
.to(approving)
.on(event1);
builder.create()
.from(approving)
.to(approved)
.on(approvedEvent)
.do(SlotChainBuilder.build()
.add(new ApprovedNotifySlot));
builder.create()
.from(approved)
.to(state2)
.on(approvedEvent);
builder.create()
.from(approving)
.to(apprvoeRefuesed)
.on(apprvoeRefuesedEvent);

现有状态内追加action。

  • 新增审批通过、拒绝事件
  • 新增审批处理Slot,在handle内实现审批校验逻辑。
    其他问题
  • 平滑迁移问题:对链路增减状态后,发布过程中如何做到平滑迁移
    • 状态机新增节点
      • 没有问题。
    • 状态机删除节点
      • 逻辑上删除了某个状态,数据库中某状态机仍是旧状态,可能会出现该旧状态无法流转到新状态的问题。
      • 解决方案一:不允许删除状态
        • 状态不允许删除,如果需要删除某状态,直接把状态对应的action置空即可。
        • 缺点:以后状态越来越多,不好维护。状态空跑也会增加无意义的消耗。
      • 解决方案二:增加版本控制
        • 对状态机增加版本控制,状态增减一次版本加+1。
        • 状态机流转路由与状态机版本匹配。一段时间后,旧版本的状态机完全处理完毕后,则可以直接下线旧版本逻辑。
        • 缺点:根据场景不同,可能旧版本的状态机下线时间不确定。
      • 解决方案三(采用该方案):持久化迁移规则快照
        • 创建状态机实例时,持久化当前状态迁移规则快照,当从内存中无法查询到对应状态迁移规则时,降级使用迁移规则快照
        • 实现简单,缺点还能接受。
    • 状态机状态数量未发生变化,但在两状态之间增加执行的节点。
      • 一个state对应一个slot chain,当State发生迁移时,会按需执行对应的slot chain。
      • 对应的slot chain追加slot即可。
  • 随着未来状态越来越多,同一个Event可能要被多个state消费。
    • 方案一:EventRouter配置多个事件路由,Event的消费target应该由EventDispather统一分发。
      • 缺点:链路长,性能不够好。
      • 优点:所有Event统一分发和消费,入口统一。统一由EventDispather管理和监控,便于事件跟踪。
    • 方案二:同一个Event配置多个观察者,即onEvent时通知到多个slot
      • 优点:链路短,且简单。
      • 缺点:存在多个事件路由逻辑:eventRouter、Event内部。
    • 倾向于方案一:
      • 开发同学上手简单、开发成本低,优于性能。

数据模型
状态机数据模型
暂时无法在飞书文档外展示此内容
其他子模块的数据模型见各模块设计文档

上下游协作
算法

  • 算法目前在处理完成xx(xx、xx)后直接发送消息到mq,如果出错会带上错误信息。但未维护任务状态。可以放在redis或者mysql里,并对外提供查询任务接口。dubbo主动查询和mq异步链路两条链路整体可靠性更高。
  • 算法侧是否可以将粗粒度的链路进一步细分,并记录每一步的状态(埋点、日志)。业务层感知后可以告警或者根据具体细分原因,采取对应的补偿策略。具体采用何种补偿策略应该根据场景和错误原因case by case去看,前期至少要先告警出来,后不断打磨。

事件、状态枚举定义
public enum StateType {
CheckXxSuccess(10000),
CheckXxFailed(10001),
PreviewXxSuccess(10002),
PreviewXxFailed(10003),
GenerateXxSuccess(10004),
GenerateXxFailed(10005);

StateType(int stateType) {
    this.stateType = stateType;
}
public int getType() {
    return stateType;
}
private int stateType;

}

public enum EventType {
CreateOrder(60000),
CheckXXSuccess(60001),
CheckXXFailed(60002),
PreviewXXSuccess(60003),
PreviewXXFailed(60004),
GenerateXXSucess(60005),
GenerateXXFailed(60006);

EventType(int eventType) {
    this.eventType = eventType;
}
public int getType() {
    return eventType;
}
private int eventType;

}

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

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

相关文章

一文多图,彻底弄懂LSM-Tree

一文弄懂LSM-Tree LSM-Tree是什么? LSM-Tree(Log Structured Merge Tree)是一种数据结构,它被设计用于处理大量写入操作的场景,常见于许多NoSQL数据库中,如BigTable、Cassandra、RocksDB和LevelDB等。 L…

废品回收小程序:回收更加便捷!

在日常生活中,废品回收已经成为了一种常见事,随着电商的快速发展,居民难免会产生大量的废纸盒等可回收物,以及在日常生活中产生的其他回收物, 目前,废品回收市场也发生了改革,传统的“叫卖”方…

MySQL高阶1990-统计实验的数量

目录 题目 准备数据 分析数据 总结 题目 写一个 SQL 查询语句,以报告在给定三个实验平台中每种实验完成的次数。请注意,每一对(实验平台、实验名称)都应包含在输出中,包括平台上实验次数是零的。 结果可以以任意…

C++之STL—常用查找算法

- find //查找元素 - find_if //按条件查找元素 - adjacent_find //查找相邻重复元素 - binary_search //二分查找法 - count //统计元素个数 - count_if //按条件统计元素个数 find (iterator begin, …

衡石分析平台系统管理手册-功能配置之全局 JS 设置

全局 JS 设置​ 衡石系统提供了全局 JS 设置功能,用户可以通过自定义 JS 代码实现系统的个性化需求,如使用第三方统计工具对系统平台的 PV 、UV 进行监测。 使用场景​ 场景1:增加百度统计​ 下图示例中使用 js 代码引用了百度网站统计功…

SUP-NeRF-ECCV2024: 单目3D对象重建的新突破

2024-09-25,由Bosch Research North America和Michigan State University联合发布的SUP-NeRF,是一个基于单目图像进行3D对象重建的新型方法。一个无缝集成姿态估计和物体重建的统一网格。 ECCV:欧洲计算机视觉会议的缩写,它是计算…

免费好用!AI声音克隆神器,超级简单,10秒就能克隆任何声音!(附保姆级教程)

今天下午还有读者问: 有没有能克隆声音的 AI 工具? 其实剪映很早就上了克隆声音的功能。 只需要按要求朗读例句,或者上传本地的音视频文件,就可以克隆声音了。 操作非常简单,效果也不错,可以试试。 除了…

数据库软题4-关系代数转SQL语言

题1 因为是笛卡尔积 <ABCD CDE> <1234 567> 笛卡尔积 RxS FROM R&#xff0c;S题2 题3 题4 题5

day-62 每种字符至少取 K 个

思路 滑动窗口&#xff1a;改变思路&#xff0c;从左右两边取字符&#xff0c;是a b c三个字符至少被取k次&#xff0c;那么意味着如果我们知道字符串中a b c的出现个数&#xff0c;那么可以知道取走后剩下子串a b c的个数&#xff0c;问题转化为了求最长子串 解题过程 如果a …

java项目开发团队分配管理软件

需求&#xff1a; 该软件实现以下功能&#xff1a; 软件启动时&#xff0c;首先进入登录界面进行注册和登录功能。 当登陆成功后&#xff0c;进入菜单&#xff0c;首先就可以对开发人员账户和密码进行修改。 然后可以对开发人员进行增删改操作 人员添加成功后&#xff0c;根据菜…

传奇GEE引擎版本如何封挂?GEE引擎设置简单的封挂脚本教程

网关参数设置gee引擎封挂脚本 1、打开M2-选项-参数设置-游戏速度 把所有的设置限速关闭 2、打开M2-选项-客户端设置-内挂控制-速度控制&#xff1a;移动速度 攻击速度 魔法速度 设置好参数&#xff0c;一旦设置不要修改 否则封挂网关参数需重新设置 打开M2-选项-功能设置-…

【C++算法】栈

删除字符中的所有相邻重复项 题目链接 删除字符中的所有相邻重复项https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/description/ 算法原理 代码展示 class Solution { public:string removeDuplicates(string s) {string ret;for(int i 0; i &l…

C# 的枚举(Enum)应用说明

一.Enum的定义&#xff1a; 枚举是一组命名整型的常量。枚举类型是使用 enum 关键字声明的&#xff0c;它是值类型。枚举包含自己的值&#xff0c;且不能继承或传递继承。 二.声明 enum 变量&#xff1a; 声明枚举的一般语法&#xff1a; enum <enum_name> { enumerati…

Harbor使用

文章目录 1、上传镜像1.1、在Harbor上创建一个项目1.2、docker添加安全访问权限1.3、推送docker镜像到该项目中1.3.1、登录到Harbor1.3.2、给镜像重新打一个标签1.3.3、推送镜像到Harbor中 2、拉取镜像2.1、先删掉原来的镜像2.2、执行拉取命令 1、上传镜像 需求&#xff1a;将…

[Python]什么是K-Means均值聚类算法?

K-Means均值聚类分析是一种无监督学习算法&#xff0c;用于将数据集分成k个簇&#xff08;cluster&#xff09;&#xff0c;其中每个簇的成员在某种意义上是相似的。算法的目标是找到质心&#xff08;centroid&#xff09;&#xff0c;使得每个点到其最近质心的距离之和最小。通…

【科研小小白】理解图片容量、像素、尺寸、分辨率各自含义、 像素、分辨率与实际尺寸之间的转换关系

理解图片容量、像素、尺寸、分辨率各自含义&#xff1a; 通过之前的学习&#xff0c;我们知道了图片有这4个参数&#xff0c;下面给大家总结一这下4个参数的具体含义。 1、容量&#xff08;占内存&#xff09;&#xff1a;是指图像文件的存贮空间&#xff0c;也就是文件的大小…

职场基本功:情绪管理的行动指南(前置情绪管理)

文章目录 引言情绪管理的目标情绪产生的阶段前置情绪管理避免情绪失控的技巧案例分析引言 成熟的职场人,必备的五项技能: 管理自己的情绪:职场需要你的行为是可控的,只有情绪是稳定的,其他人才能顺利地跟你展开协作。称赞他人:赞赏能让你获得一个友好的交流环境求助他人…

lte sss加扰序列c产生 MATLAB和c语言实现

参考3GPP 36.211 今日给大家介绍一下LTE SSS信号产生过程中加扰序列c的产生过程以及用MATLAB 和 c语言给大家实现一下&#xff1a; 加扰序列c产生过程如下&#xff1a; 1 首先产生公共的序列x的生成 X的初始值 两个加扰序列c0和c1 c语言实现 void lte_sss_gen_c(char *c,u…

Zlibrary安装包下载与使用

文章目录 Zlibrary安装包下载与使用一 写在前面网盘链接1 百度网盘链接2 夸克网盘链接3 阿里云盘 二 安装1 Windows系统2 安卓3 苹果电脑端4 Linux系统Ubantu的下载与安装 三 Zlibrary的使用四 写在最后 Zlibrary安装包下载与使用 2024年9月27日下午4点 一 写在前面 1 Zlibr…

智慧农业案例 (一)- 自动化机械

橙蜂智能公司致力于提供先进的人工智能和物联网解决方案&#xff0c;帮助企业优化运营并实现技术潜能。公司主要服务包括AI数字人、AI翻译、领域知识库、大模型服务等。其核心价值观为创新、客户至上、质量、合作和可持续发展。 橙蜂智农的智慧农业产品涵盖了多方面的功能&…