The architecture of the simple application framework VSEF





This article introduces some understanding of the framework structure of some simple architecture VSEF, and throws out some evolutionary themes. Different thinking on these will make the system develop into different styles, which is actually the inevitable result of application positioning.


overall

VSEF architecture concept  =   basic structure  + evolution
  1. Basic structure = entry + kernel + dependencies
    Core = simple logic + complex process
    Simple logic = business script + capability execution
    Complex process = process orchestration + node connection + capability (task) execution
  2. Evolution = topic discussion + component selection (market components are given priority)
    
VSEF overall structure

core architecture

Architecture = Components + Relationships + Design/Evolution Principles


▐Entrance _  


VSEF point of view: The entrance should be clear and clear

Just like "to sort out a messed up thread, you need to find the thread ends." The advantage of placing the entry in a complete directory or module is that you can quickly get an overview of the functions and understand "what services are provided" and "receive those messages” and “what tasks are achieved”.


The directory types here are:

  1. Service service : RPC service provided externally, such as HSF. This is generally used with a service client callable.

  2. Message message : Metaq and notify directories can be distinguished again.

  3. Scheduling scheduler : some scheduling tasks.


Business entrance


Kernel  


After business logic enters, the common structure is Service + Component + Mapper. However, as the number of operating links increases, they will gradually become intertwined and coupled, becoming complex. Therefore, some designs are needed, including: vertical layering, horizontal directory division, and defining reuse areas to alleviate the complexity caused by code placement issues.

VSEF perspective: Kernel = simple logic + complex process

Kernel structure


Complex processes , mainly write services, or detailed services with page expressions, use the Process Classification Framework (PCF). When entering the application, it is mainly divided into three layers:
  1. Process l3.process : arrange business activities and understand what the entire request is to accomplish.
  2. Activity l4.activity : Provides the ability to execute each step and represents the key node of the matter.
  3. Ability (task) l5.ability : Some specific tasks to be done when the node is executed. It is expected to be packaged as capabilities and have a certain degree of reusability.

Process Classification Framework PCF Hierarchy


For simple processes , mainly read-only services, such as querying data, you can directly enter the service script service. Simple services use l5 capabilities (tasks) directly. When the logic becomes increasingly complex, it can be reconstructed into a complex process.



VSEF point of view: The resources needed to complete the task are all dependencies, and all dependencies are services. Services are all used through L5 capabilities.


When l5 capabilities perform specific operations, they need to obtain the data that needs to be processed from data, extensions, external transfer, middleware and other channels to form their own understanding. In this process, the dependent things are called "dependencies" and are integrated through "services".


▐Dependence _  


Types that can be put into dependencies:

  1. Storage implementation repository : database read and write operations.

  2. Middleware uses middleware : including caching (tair), sending messages (metaq, notify), configuration (diamond, switch), etc.

  3. Gateway implements gateway : calls to external systems, such as order services, refund services, etc.

  4. Extension implementation extension : The expansion capability of business differentiation design requires the business to provide extension plug-ins or the platform to write them.


Depends on content

VSEF’s point of view: You can judge whether the infrastructure is volatile or not, and you can directly rely on it when it is stable.


What is worth discussing here is: If based on the hexagonal architecture, these infrastructures are regarded as concrete implementations and should be decoupled through abstract interfaces and a dependency inversion strategy. But in fact, in our system, we can judge its variability. If it remains stable for a long time, we can reduce the dependence on the abstraction layer, rely directly on the infrastructure, reduce the cost of abstraction, and achieve less is more at the thinking level.


Theme evolution

The VSEF directory is just an initialized, relatively simple system structure. If as the business develops, each component will gradually become bloated, and the system style may also change. Therefore, it is necessary to introduce some topic discussions, conduct some designs based on business conditions, select relevant components, and integrate them to form an application structure with specific organizational characteristics and new features.


VSEF perspective: The evolved system structure, combined with functional features, is the appropriate system structure for each organization.


Such system structures may differ greatly from each other and become different types, just like the seven gourd dolls, with different core capabilities:
  1. Those who focus on platform services : focus on platform logic and expansion mechanisms.

  2. Pay attention to component expression : to interact with users, you need to pay attention to componentized protocols.

  3. Those who focus on domain collaboration : need to pay attention to the model and design of the coordinator and the domain division logic within the application.

  4. Those who focus on data services : focus on data capability performance, functional scope, and data model mapping.


VSEF theme


Next, I will briefly talk about thinking based on the theme of VSEF. With this part, you will know how to choose components, instead of being "kidnapped by the weight of the components" and avoid using them for the sake of use, which is actually inappropriate.

▐Component Agreement  


If the system is platform-based and has interface expression, then what needs to be solved is the different scalability of each terminal, each page, and each business. It is a good idea to add a layer of ViewModel between the internal model and the view model, and then perform various conversions based on this. Typical components include: Ultron, Astore, etc.


Model-View-ViewModel (MVVM) pattern


To break it down here, there are two different directions regarding how customized the ViewModel can be:

  1. The conversion is mainly in the component framework : in addition to the core logic, various frameworks are implanted, such as Ultron and Astore, and conversion is performed on the data export side. The conversion method is generally based on regular expressions and uses relevant reflection capabilities for data assembly. .

  2. The conversion is mainly in business expansion : I don’t want to carry too much code in the component framework, and I want to be closer to the ordinary expansion logic of the business. In the expansion logic during system execution, the expansion of the view can better match the front-end components. .


Altron&DinamicX solution operating principle


▐Event arrangement  


流程编排是对一个业务操作执行过程进行进一步的划分,常见的编排组件有: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等理论与实践,致力于高效、稳定地实现业务接入,并抽象赋能。

¤  拓展阅读  ¤

3DXR技术 |  终端技术 |  音视频技术
服务端技术  |  技术质量 |  数据算法



本文分享自微信公众号 - 大淘宝技术(AlibabaMTT)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

博通宣布终止现有 VMware 合作伙伴计划 deepin-IDE 版本更新,旧貌换新颜 WAVE SUMMIT 迎来第十届,文心一言将有最新披露! 周鸿祎:鸿蒙原生必将成功 GTA 5 完整源代码被公开泄露 Linus:圣诞夜我不看代码,明年再发布新版 Java 工具集 Hutool-5.8.24 发布,一起发发牢骚 Furion 商业化探索:轻舟已过万重山,v4.9.1.15 苹果发布开源多模态大语言模型 Ferret 养乐多公司确认 95 G 数据被泄露
{{o.name}}
{{m.name}}

Guess you like

Origin my.oschina.net/u/4662964/blog/10322158