阅读说明:
如果有排版格式问题,请移步 [《业务单系统架构设计心得(一)》](https://www.yuque.com/mrhuang-ire4d/oufb8x/ilud3u0w74sthfpo?singleDoc# 《业务单系统架构设计心得(一)》),选择宽屏模式效果更佳。
本文为原创文章,转发请注明出处。
作为一个业务开发工程师,工作中最多的是需求开发,把需求从ppt到落地实现。随着工作的深入,工作面也变得更广和更深,需要面对更多的系统,更加复杂的场景。这时完成功能实现是基本要求了,想要开发能力上一个台阶,需要做好架构设计。常见的架构有:洋葱架构、六边形架构、整洁架构、SOA架构、CQRS架构等等。
这些架构都有一个共同点,分层。针对业务开发系统,本文总结如下业务架构,总共分为5部分:api层、流程层、服务层、数据访问层、指令输出层。
1.api层
功能:隔离本系统与外部其他系统的交互,交互方式有rpc接口,http,mq, 定时任务等方式。 api层接收和处理入口参数以及凭借和转换参数,映射为内部服务,并处理内部服务出参。api层不只是做转换,还需要理解内部服务的模型定义和领域能力,对参数建立合理的模型。
api层在设计上需要尽量满足以下四个原则:
- api层尽可能薄。api层不要业务逻辑,业务逻辑下沉到流程层和服务层里面。
- 满足弹性设计,减少后续对api定义的改动。api层是跟外部交互,接口定义上尽量减少变动。弹性设计方法有:
- 对入参和出参使用一个大对象包装,后续变更参数时,变动收缩在对象内部;
- 使用Map来传递一些可变参数;
- 通过List实现参数规模的弹性,不断丰富Condition模型来支持更多的参数结构和含义,比如范围搜索、模糊搜索、并联或者互斥条件含义。
- 参数归一化。所有外部的请求,业务上一般需要记录上游方的调用信息,方便后面追溯请求和做业务监控。因而,需要抽离出公共模型,专门记录调用方相关信息。所有返回结果,根据是否成功有可能性:成功,失败。 在定义成功和失败上,为了便于上游,需要统一成功和失败的code,在设计返回结果时需要抽离出一个标准返回模型,统一定义成功和失败的code。比如http,只有200才表示成功,其他错误码都是不同失败原因。
- 上游参数映射:尽力隔离上游系统的领域内容,防止上游定义变更,带来的大批量修改灾难。
当然,api层可以做一些非业务功能,比如用户鉴权,接口限流。
2.流程层(biz层)
负责流程编排。将服务层的逻辑串联起来完成业务逻辑。流程层主要负责组织串联服务,可以将组织串联功能沉淀出基础组件功能便于复用。 流程层可以留有简单的业务逻辑,如果本身不复杂,业务逻辑可以直接放到流程层,不必下沉到服务层再被流程层调用,业务架构设计中可根据情况具体分析。
3.服务层(service)
系统核心模型和能力弹性的承载层,是系统功能和扩展性张力来源。服务层内部要进行划分成不同的功能区,划分方法可参考DDD,原则上各个功能区是独立的,不应存在跨功能区调用的情况。
4.数据访问层
对接数据存储,对外提供统一的接口,屏蔽存储实现,数据存储有mySQL, Redis, ES等。
5.输出指令层
输出指令数据,方式有RPC, MQ, 以及http等服务。在层级上跟数据访问层处于同一层级。输出指令层也是跟外部服务进行交互,如有必要进行参数映射,防止下游定义变更,带来的大批量修改灾难。
业务复用
随着系统壮大,越来越多新的功能加入,如果新功能跟现有功能在流程上具备相似之处,从原则上应该复用现有逻辑。复用现有逻辑,一方面能够减少开发量,只需要专注差异点的开发,能够快速交付上线;另一方面,从长远来看,便于维护,无需多次改动。
不同业务具备公共业务点和差异业务点,业务复用可以在两个地方实现:流程层重新编排和服务层子服务开启差异点扩展。
流程层重新编排是指各个业务线在流程层各自写一套服务编排逻辑,被编排的子服务可以分为公共子服务和差异子服务, 公共业务点放到公共子服务中,差异业务点放到差异子服务。
服务层子服务开启差异点扩展是指流程编排是相同的,在子服务中根据不同的业务线实现差异点,为了在子服务中实现差异点,需要在流程上下文中带上业务标识。
流程层重新编排适合差异点比较大的情况下,差异子服务并非一个服务的不同实现,这种情况下将差异点直接编排成子服务更合适。服务层子服务开启差异点适合差异比较小的场景,对于某个功能点各个服务都有自己不同的实现,这种有个好处是便于定义标准扩展接口,做成SPI还能够支持动态扩展。实际业务线采用哪种方式要根据具体业务来定,或者两种都采用。
扩展点
一个系统能够成为优秀系统,扩展能力是一个必备的能力。良好的扩展能力不仅能够帮助系统提高扩展,增强适应性,还能够简化系统结构,代码更加优雅。java中提供了多种机制对程序功能进行扩展,如继承,组合,多态,接口,内部类等,框架类比如Netty, Spring同样提供了大量自定义扩展点。同理,在业务系统架构设计中,剥离出变动部分,并设计为扩展点的形式,方便后续迭代。
链式扩展
用更形象的表述,就如数据结构中的链表一样,链表中的节点为扩展节点,链表将多个扩展节点串联起来执行。链式又可以分为单链和双链。单链中每个节点只有一个处理器,双链每个节点分为前置和后置处理器,双链在执行上,节点前置处理器先正序执行,执行完后,后置处理器再逆序执行。
链式扩展由扩展节点(扩展点的具体实现), 扩展节点链组成。链式扩展的扩展节点实现具备同等地位,图中ExtensionOne, ExtensionTwo, ExtensionThree都是对同一扩展点的不同实现。注册Extension时,将扩展节点编排成链,如果扩展节点无前后依赖关系,那么节点执行顺序可以任意编排。当然,有些扩展点是有前后的依赖关系,这种情况下就必须指定节点执行顺序。在Spring中,注册Extension变得更加简单。直接自动从Spring中上下文中找到所有扩展点的实现节点,在修改节点时,无需改动注册逻辑。
链式扩展应用广泛,在SpringMVC中,实现拦截器,提供日志打印,权限校验等工作。在订单业务系统中,也有很多应用。比如订单拆单流程,业务上有很多拆单规则比如大小件拆开,按照发货仓库拆开等等,一个订单经过拆单规则后,将拆分成多个子单。拆单规则通常是动态变化的,这里就非常适合采用链式扩展点。
星型扩展
星型扩展组成上有一个分发器和多个扩展节点。分发器根据分发条件分发到响应的扩展点进行处理。
星型扩展逻辑简化如下:
if (命中业务A) {
执行ExtensionOne;
} else if (命中业务B) {
执行ExtensionTwo;
} else {
执行ExtensionThree;
}
星型扩展的应用也很多,上一节中的业务复用,在服务层子服务开启业务复用,需要开启星型扩展来处理不同业务的差异点。 SPI虽然没有明显分发器,但也属于星型扩展的方式。文章来源:https://www.toymoban.com/news/detail-802625.html
参考:
[1]. https://zhuanlan.zhihu.com/p/479800537
[2].https://medium.com/expedia-group-tech/onion-architecture-deed8a554423
[3].https://mp.weixin.qq.com/s/pNfC7klCZTKhXwC4t5V7BA
[4].https://mp.weixin.qq.com/s/F42LqQncMDLQH-WWmZ28fA
[5].https://mp.weixin.qq.com/s/y-RBStzS0jNlbkljRP_MrA文章来源地址https://www.toymoban.com/news/detail-802625.html
到了这里,关于业务单系统架构设计心得(一)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!