简洁应用框架VSEF的架构

简介: 简洁应用框架VSEF的架构




本文介绍了一些简洁架构VSEF的一些框架结构理解,并且抛出了一些演化的主题,这些主题的不同思考会让系统发展成不同的风格,实际也是应用定位的必然结果。


总体

VSEF 架构理念 =  基本结构 + 演化

  1. 基本结构 = 入口 + 内核 + 依赖内核= 简单逻辑 + 复杂流程简单逻辑 = 业务脚本 + 能力执行复杂流程 = 流程编排 + 节点衔接 + 能力(任务)执行
  2. 演化 =  主题讨论 + 组件选取(市场组件优先)

VSEF 总体结构
核心架构

架构 = 组成要素 + 关系 + 设计/演化原则


 入口


VSEF 观点:入口要清晰明确

就像 “要理清乱了的线团,就要找到线头一样”,将入口放在一个完整的目录,或者模块中的好处是:可以快速地功能总览,了解“提供哪些服务”、“接收那些消息”、“实现哪些任务”。


这里的目录类型有:

  1. 服务 service : 对外提供的 rpc 服务, 如HSF。这个一般会搭配一个服务 client 可调用者使用。
  2. 消息 message:可以再区分 metaq 和 notify 目录。
  3. 调度 scheduler:一些调度任务。


业务入口


 内核


业务逻辑进入之后,常见的结构是 Service + Component + Mapper。但随着操作链路的增多,会逐渐交织耦合,变得复杂。所以,需要一些设计,包括:纵向的分层、横向的目录划分、并定义复用的区域,缓解代码安放问题造成的复杂度。
VSEF 观点:内核 = 简单逻辑 + 复杂流程

内核结构


复杂流程,主要是写入服务,或者是带页面表达的详情服务,采用流程分类框架(Process Classification Framework,PCF)。进入到应用的时候,主要分为3层:

  1. 流程 l3.process:进行业务活动编排,理解整个请求要完成什么事情。
  2. 活动 l4.activity:提供每个执行步骤的能力,代表了事情的关键节点。
  3. 能力(任务) l5.ability:节点执行时要做的一些具体任务,期望包装为能力,具备一定的复用性。


流程分类框架 PCF 层次


简单流程,主要是只读服务,如查询数据等,可以直接进入服务脚本 service。简单服务直接使用 l5能力(任务)。当逻辑逐渐复杂的时候,可以重构为复杂流程。



VSEF 观点:完成任务需要使用的资源都是依赖,依赖皆服务。服务都通过 l5能力 进行使用。


l5 能力在进行具体操作的时候,需要从数据、扩展、外调、中间件等渠道获取需要加工的数据,形成自己的理解。这个过程中,依赖的东西被称为“依赖”,通过“服务”的方式进行集成。


 依赖


可以放进依赖的类型:

  1. 存储实现 repository : 数据库的读写操作。
  2. 中间件使用 middleware:包括缓存(tair)、发送消息(metaq、notify)、配置(diamond、switch)等。
  3. 网关实现 gateway:外部系统的调用,比如订单服务、退款服务等。
  4. 扩展实现 extension:业务差异性设计的扩展能力,需要业务提供扩展插件,或者平台代写。


依赖内容

VSEF 观点:基础设施是否易变,可自行判断,稳定时可以直接依赖。


这里值得讨论的是:如果基于六边形架构,这些基础设施被视为具体实现,应该通过抽象接口,依赖倒置的策略,实现解耦。但是实际在大家的系统中,可以判断其易变性,如果长期保持稳定的话,可以减少依赖抽象这一层,直接依赖基础设施,减少抽象成本,在思考层面做到 less is more。


主题演化

VSEF 的目录只是一个初始化、相对简单的系统结构。如果随着业务的发展,各个组成部分会逐渐臃肿,系统风格可能也会变化。所以需要引入一些主题的讨论,结合业务情况进行一些设计,并选取相关组件,进行集成,形成有具体组织特征的、新特性的应用结构。


VSEF 观点:演化后的系统结构,结合了功能特性,才是各个组织的合适的系统结构。


这样的系统结构可能会彼此差异很大,会成为不同的类型,就像七个葫芦娃一样,核心本领各不一样:

  1. 注重平台服务的:关注平台逻辑和扩展机制。
  2. 注重组件表达的:与用户有交互,需要关注组件化协议。
  3. 注重领域协作的:需要关注协调者的模型和设计、应用内的领域划分逻辑。
  4. 注重数据服务的:关注数据能力性能、功能范围、数据模型映射。


VSEF 主题


下面,会基于VSEF的主题,简单谈一下思考,有了这一部分,才会知道如何去选择组件,而不是“被组件的厚重所绑架”,避免为了用而用,实际并不合适。

 组件协议


如果系统是平台型的,并且带界面表达,那么需要解决的就是各个端、各个页面、各个业务不一样的扩展能力。在内部模型和视图模型之间增加一层ViewModel, 然后基于这个进行各种转换,是不错的思路,比较典型的组件有:奥创、Astore等。


Model-View-ViewModel(MVVM) 模式


这里细化开来,关于 ViewModel 能够有多定制,有2个不同的走向:

  1. 转换主要在组件框架中:在核心逻辑之外,进行各种框架植入,如奥创、Astore, 在数据出口侧进行转换,转换的手段一般是基于规则表达式,利用相关反射能力进行数据组装。
  2. 转换主要在业务扩展中:不想在组件框架中承载过多代码,想和业务普通扩展逻辑走的近一些,在系统执行过程中的扩展逻辑中,植入视图的扩展,可以较好匹配前台组件。


奥创&DinamicX 方案运行原理


 活动编排


流程编排是对一个业务操作执行过程进行进一步的划分,常见的编排组件有:Tbbpm、SmartEngine 等。但在实际开发过程中,常常会有这样的疑惑:为什么是这几个节点?为什么是这样的顺序?


  • 为什么是这些节点?


这和我们看到一段非常长的代码,把它切分成几个方法是类似的。关键是切分的依据是什么?常用的一些划分点有:

  1. 是不是调用了一个服务?那么准备服务参数,调用,返回结果判断可以包装为一个节点。
  2. 是不是都在操作一个对象?那么这些操作可以归类为:初始化,修改,转换等内聚的方法。
  3. 是不是一些通用的处理?比如安全校验、日志监控、数据统计等。
  4. 是不是存在业务扩展性?可以单独独立出来,作为抽象方法,或者使用组合,提供相关接口定义。


切分的背后是理解

  • 为什么是这样的顺序


基于这些切分原则,可以对一个执行过程的核心要点进行切分,切分完后排序的依据是什么?为什么一定要是这样的顺序?这个问题本质是需要了解各个部分的依赖关系,这些依赖关系可能是:

  1. 上下文数据依赖
  2. 本身地位:需要对最终结果进行收口,需要最后执行。
  3. 系统框架要求必须进行初始化先执行
  4. 其它等等


那么我们可以去梳理这些依赖关系,形成一个有向无环图,最后变成寻找了拓扑排序这样的问题

  1. 每个顶点出现且只出现一次
  2. 若存在一条从顶点 A 到顶点 B 的路径,那么在序列中顶点 A 出现在顶点 B 的前面


有时候,这个顺序是唯一的,但是大多数时候这个顺序是不唯一的,所以我们更应该去了解内部的依赖关系,而不是纠结于表面的顺序。

排序的背后是依赖


 设计模式


在比较重的业务逻辑处理过程中,除了集成一些框架、目录与jar包层次的设计之外,比重最大的启示是普通 java 代码,而这些能够影响最大的是,是设计原则与设计模式。这些应该是不能忽略的点。
常见的场景举例有:

  1. 模版方法:模版方法是说对一个执行过程进行抽象分解,通过骨架和扩展方法完成一个标准的主体逻辑和扩展。平台和扩展能力的设计,做类比是比较合适的。基础的模版就是整个流程的编排和对应的节点,可扩展的地方就是各种业务定制区域。这样形成了平台和业务较好的融合。
  2. 策略模式:策略是说完成一个事情有不同的算法,可以进行相关切换。在逆向退款中,需要支持不同的退款链路,有些需要是担保交易,有些是保证金链路,有些是微信支付,有些是退卡、退资产。为了支持多种出账策略,采用了策略模式,可以通过扩展点定制各种资金策略。
  3. 责任链模式:责任链是说将请求让队列内的处理器一个个执行,直到找到愿意执行的。扩展中,在执行回收结果的时候,会遍历实现的插件,并结合回收规则,进行及时的熔断。
  4. 观察者模式:观察者模式是说我们通过注册、回掉这样的协作设计,完成变化通知的协作机制。系统间基于消息的观察模式还是很多的。通过消息的异步通知方式,既可以较好地进行解耦,也可以在失败时利用消息的重投机制,增加成功的概率。
  5. 中介者模式:当多个类之间要协调的时候,往往引入中介者进行协调,减少大家的知识成本。系统中的流程执行过程中,会有一个大的上下文,这个上下文会协调各个领域的数据。

......


常见的策略模式


 元数据


当内部结构开始复杂的时候,就期望使用一些元数据。一方面,期望这个能够将理念传达给开发者,知道对应类的角色。另一方面,这部分的扫描,可以形成结构知识,并通过各种数据转存,在另外一个系统无关的页面进行展示,可以站在更高地抽象和中文描述层次,更好地方便大家理解。

认知复杂性:度量理解软件所需要的努力,即捕获程序的逻辑流,并度量逻辑流的各种特性。


简单元数据设计


 复用独立


单刃为刀,双刃为剑。们在用这个双刃剑的时,当一面对着敌人,另一面一定会对着自己,这时如果将剑刃对着敌人砍去的时候,敌人用兵器一挡,剑就会反弹回来,对自己就会有一定的危险。


代码复用是一把双刃剑。复用意味着代码的影响面会增加,虽然提高了开发效率,但是一但进行改动,影响范围变大的副作用也很明显:要求你得足够了解影响的范围,进一步增加了认知的复杂性。在影响较大的情况下,不合理的复用会产生很多令人崩溃的补丁逻辑。

  1. 有时,为了业务独立快速迭代,会独立逻辑,因为我们预判一直演化下去最终可能会产生两份完全不同的代码。
  2. 有时,虽然业务逻辑看上去不太一样,但是我们会收口到一起,尽量复用一份逻辑,因为我们预判发展下去会产生更多的复用逻辑。


到底是分还是合?哪些要复用?哪些要独立发展?显然与我们的预判息息相关。总的来说,离“业务”越近的地方,应该越尽可能独立,离“平台”越近的地方,应该近可能复用,代码是否稳定是重要的判断因素。


订单管理系统中复用独立的不同场景


 领域划分


在VSEF里面,淡化了领域的概念,因为认为领域都在网关服务里面,而系统本身的领域,则分散在能力里面,对外整体作为一个领域。


领域中,关于领域的划分是很非常挑战的,相关思考,在我们的能力划分,目录的设计等方面都可以借鉴:

  1. 思想一:看核心管理数据载体。
    我们可以认为一个域实际上是一个或多个实体对象的信息集合,并对所管理的实体对象的生命周期进行管理。
  2. 思想二:确定核心白名单,其它可扩展。既然无法维护一个涵盖整个企业的统一模型,那就不要再受到这种思路的限制。通过预先决定什么应该统一,并实际认识到什么不能统一,我们就能够创建一个清晰的、共同的视图,然后需要用一种方式来标记出不同模型之间的边界和关系。


此外,我们常常会发现划分调整的背后事务:

  1. 调整的内容:其实是匹配生产关系。
  2. 调整的原则:追求职责的内聚,精细化分工。
  3. 不断调整的原因:业务在发展,内聚的标准需也要与时俱进。


从关联的角度看,往往我们看组织架构,就能看到领域的边界,核心原因还是组织架构也是要适应生产关系,follow更优解的结构,是相辅相成的,也就能互相窥探。


领域的划分应该尽可能正交

 逻辑模型


在数据库操作的时候,在数据服务的路口,选择逻辑模型是天然的一个选择。比如属性,在逻辑模型中可能是一个map,在DO中是一个String,如果使用DO流转,就会非常不方便。


这里还可以探讨的是,逻辑模型应该如何抽象?要不要聚合多个表。最容易理解、维护以及发展的情况,当然是领域模型与数据模型能够形成1:1的维护关系。但是由于底层数据很难变动,而理解和业务发展是与时俱进的,当我们持续设计的时候,逻辑模型势必会不太一样。常见的一些场景有:

  1. 一个逻辑模型维护一个表:这个是比较简单的场景,一个逻辑模型直接负责一个表,比较干净易理解。
  2. 多个逻辑模型共享一个表:这个是因为表中记录的数据比较多,但是实际上有不同的领域数据存的冗余储,比如交易订单上的营销优惠信息、资金信息、物流信息等。
  3. 一个逻辑模型维护多个表:当我们对原始的领域重新划分,又不能重新建立表结构的时候,对于较大的一些域,往往数据来自多个表,这时候就会遇到这样的情况,一个领域模型要从多个数据库表里面聚合数据。
  4. 聚合逻辑模型的复杂情况:这个在DDD里面主要是聚合根这样聚合了多个实体的情况。举个例子来说,资金单有支付单、垂直表、还有多个支付单,这样的聚合关系就更加复杂了。


逻辑模型与物理模型映射场景


 模型策略


当我们获得外部对象的时候,选择follow,还是选择拷贝,还是选择抽象定义。这里有不同的策略:

  1. 共享内核 shared kernel :通常是共享核心领域或者是一组通用子领域。
  2. 客户/供应商关系 customer/supplier:上下游关系。不同客户需要协商来平衡,上游团队需要有自动测试套件。
  3. 跟随者模式 conformist:单方面跟随模式。上游的设计质量较好,容易兼容,可以采用严格遵循上游团队的模型。
  4. 防腐层 anticorruption layer:防腐层、隔离层,使用 facade 等模式,减少其它系统变动对本系统的影响。
  5. 各行其道 separate way:声明一个与其它上下文毫无关联的限界上下文,使开发人员能够在这个小范围内找到简单、专用的解决方案。


战略设计策略


 扩展机制


如果只是基于模式扩展,可能采用一些局部的策略模式就可以了。但是如果期望服务多个业务,且期望隔离业务定制,那么就需要提供一些插件包,隔离权责出来。


更为主要的是,不同的插件包,在运行态如何执行,如果有多个满足条件,该如何定义优先级。这里逃不掉的是一个插件身份的定义。这个定义可以有很多的玩法,不同的业务组织可能理解不一,这可能是扩展机制的核心难题。

每个层次都可以设计自己的扩展机制


  1. 无论是扩展框架TMF的迭代,还是后面星环体系的提出,一个重要的目的是为了解决“业务和平台的隔离”,这也是开闭原则的重要体现。核心逻辑应该由比较熟悉的平台人员进行控制,应该尽量通用,较少修改;扩展逻辑应该由业务开发人员理解,应该尽量灵活,便于调整。
  2. 往系统内部看,其实还有很多域能力的扩展,比如:支付的时候可以走直连支付宝,也可以经过支付系统链接到微信等非支付宝渠道。这样的扩展,也是开闭原则的体现,只是离核心流程更近,影响面更大。
  3. 往扩展外部看,即使是业务APP包、产品包等插件内部,还是可能会服务多个行业、多个场景,可能有很多的再次路由与扩展。比如:淘系要服务很多行业,服饰、家电等,不同业务定制也不太一样,往往会用一些策略、责任链的扩展模式。


“聚类”是插件的基因


组件选取


不同业务组织,在进行相关主题的讨论与思考后,会定制一套适合自己的发展结构。后面在快速启动的时候,期望有一些复用的组件。这部分组件,分为外部市场的组件,和自己建立的组件。


组件分为市场已有的组件,还有自己期望自建的组件,这里VSEF框架中会提供一些概念组件。


 市场组件


市场组件应该被优先选择,因为那个是服务更多场景的,有更强的包容性。当然,如果系统比较小除外。如果定位比较大,那么还是建议及早引入,随着流量的增加,理解也不断增加,越到后面,越能巧妙应用。


交易系统中使用的一些组件举例如下:

  1. 协议化组件:Ultronage、Astore
  2. 流程编排组件:Tbbpm、SmartEngine
  3. 扩展组件Lattice、TMF
  4. 配置化组件:Newton


市场组件的一些案例


 VSEF组件


有些组件功能比较小,甚至可以作为工具类Util, 但是如果应用内有多个应用Application,想抽象复用的话,可以独立出来单独的组件,进行统一设计,避免重复劳动。
可能的一些组件设计有:

  1. 元数据组件:Metadata , 期望能够生成知识索引数据。
  2. 日志组件:CommonLog,期望能够统一格式,方便统一监控、清理。
  3. 预热组件:Preheat,期望能够抽象接口预热方式,便于预热操作。
  4. 适配器组件:Adapter,一些市场组件的抽象包装,快速集成。
  5. 扩展组件:Extension,简单扩展组件,解决系统扩展性问题,且不那么得重。


VSEF组件的一些案例


总结


本文介绍了一些简洁架构VSEF的一些框架结构理解,并且抛出了一些演化的主题,这些主题的不同思考会让系统发展成不同的风格,实际也是应用定位的必然结果。最后介绍了一些组件的部分,这个部分应该是水到渠成的结果,而不应该是事先预设的标准。


团队介绍

我们是交易平台-平台产品服务团队。团队主要从事交易链路交付工作,在交付工作中,抽象和建设横向产品能力(如:预售、电子凭证等),团队关注业务架构、DDD等理论与实践,致力于高效、稳定地实现业务接入,并抽象赋能。

相关文章
|
3月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
686 3
|
1月前
|
人工智能 JavaScript 前端开发
GenSX (不一样的AI应用框架)架构学习指南
GenSX 是一个基于 TypeScript 的函数式 AI 工作流框架,以“函数组合替代图编排”为核心理念。它通过纯函数组件、自动追踪与断点恢复等特性,让开发者用自然代码构建可追溯、易测试的 LLM 应用。支持多模型集成与插件化扩展,兼具灵活性与工程化优势。
199 6
|
2月前
|
人工智能 Cloud Native 中间件
划重点|云栖大会「AI 原生应用架构论坛」看点梳理
本场论坛将系统性阐述 AI 原生应用架构的新范式、演进趋势与技术突破,并分享来自真实生产环境下的一线实践经验与思考。
|
2月前
|
机器学习/深度学习 人工智能 vr&ar
H4H:面向AR/VR应用的NPU-CIM异构系统混合卷积-Transformer架构搜索——论文阅读
H4H是一种面向AR/VR应用的混合卷积-Transformer架构,基于NPU-CIM异构系统,通过神经架构搜索实现高效模型设计。该架构结合卷积神经网络(CNN)的局部特征提取与视觉Transformer(ViT)的全局信息处理能力,提升模型性能与效率。通过两阶段增量训练策略,缓解混合模型训练中的梯度冲突问题,并利用异构计算资源优化推理延迟与能耗。实验表明,H4H在相同准确率下显著降低延迟和功耗,为AR/VR设备上的边缘AI推理提供了高效解决方案。
405 0
|
1月前
|
机器学习/深度学习 自然语言处理 算法
48_动态架构模型:NAS在LLM中的应用
大型语言模型(LLM)在自然语言处理领域的突破性进展,很大程度上归功于其庞大的参数量和复杂的网络架构。然而,随着模型规模的不断增长,计算资源消耗、推理延迟和部署成本等问题日益凸显。如何在保持模型性能的同时,优化模型架构以提高效率,成为2025年大模型研究的核心方向之一。神经架构搜索(Neural Architecture Search, NAS)作为一种自动化的网络设计方法,正在为这一挑战提供创新性解决方案。本文将深入探讨NAS技术如何应用于LLM的架构优化,特别是在层数与维度调整方面的最新进展,并通过代码实现展示简单的NAS实验。
|
3月前
|
Web App开发 Linux 虚拟化
Omnissa Horizon 8 2506 (8.16) - 虚拟桌面基础架构 (VDI) 和应用软件
Omnissa Horizon 8 2506 (8.16) - 虚拟桌面基础架构 (VDI) 和应用软件
239 0
Omnissa Horizon 8 2506 (8.16) - 虚拟桌面基础架构 (VDI) 和应用软件
|
3月前
|
人工智能 自然语言处理 JavaScript
Github又一AI黑科技项目,打造全栈架构,只需一个统一框架?
Motia 是一款现代化后端框架,融合 API 接口、后台任务、事件系统与 AI Agent,支持 JavaScript、TypeScript、Python 多语言协同开发。它提供可视化 Workbench、自动观测追踪、零配置部署等功能,帮助开发者高效构建事件驱动的工作流,显著降低部署与运维成本,提升 AI 项目落地效率。
358 0
|
3月前
|
机器学习/深度学习 数据采集 存储
技术赋能下的能源智慧管理:MyEMS 开源系统的架构创新与应用深化
在全球能源转型与“双碳”战略推动下,MyEMS作为基于Python的开源能源管理系统,凭借模块化架构与AI技术,助力重点用能单位实现数字化、智能化能源管理。系统支持多源数据采集、智能分析、设备数字孪生与自适应优化控制,全面满足国家级能耗监测要求,并已在制造、数据中心、公共建筑等领域成功应用,助力节能降碳,推动绿色可持续发展。
118 0
|
4月前
|
人工智能 数据可视化 Java
什么是低代码(Low-Code)?低代码核心架构技术解析与应用展望
低代码开发正成为企业应对业务增长与IT人才短缺的重要解决方案。相比传统开发方式效率提升60%,预计2026年市场规模达580亿美元。它通过可视化界面与少量代码,让非专业开发者也能快速构建应用,推动企业数字化转型。随着AI技术发展,低代码与AIGC结合,正迈向智能化开发新时代。