业务中间件设计方法论经验总结
1 什么是业务中间件
在说“业务中间件”之前先解释下什么是“中间件”,通常来说中间件是特指计算机系统中将底层逻辑屏蔽,并收敛某些通用功能构建出来的软件服务。目的是用来解耦底层实现细节,更简单的进行上层业务功能开发,比如常用的redis、levelDB、kafka、rpc 本质上都属于技术中间件的范畴。
而业务中间件理我们也并不远,也是类似的思想,抽离相对通用的业务功能部分并集成特定技术,解决业务开发的复杂性等痛点问题。
举个例子来说:
image.png
我们要实现集中的对象存储,每次去显示的感知磁盘操作、内存操作、网络通信、数据结构的处理细节,一个简单的write就相当费劲了,这种时候把上述公用的操作逻辑进行收敛,然后作为一个标准的产品形态对外开放就是我们常用的“对象存储中间件”。
image.png
如果我们的业务场景是活动,每次都需要在存储之上进行一些比如“库存管理”、“分片处理”、“计数统计”等等操作,如果每次都去重复开发,成本是很高的,所以就抽象一些公共函数集中管理对于存储的处理,然后增加一些易用性及通用性的处理,再进一步抽象在特定活动领域下,标准化成产品能力,就是所谓的业务中间件,比如库存管理工具、高可用账务工具、规则决策引擎等等。
2 痛点的发现及分析
业务中间件的设计是用来解决问题的,尤其是痛点问题的,比如说:维护成本、开发成本、性能风险、数据一致性保障风险。
所以,第一步是分析我们当前的业务系统,面对当前的业务现状存在什么样的痛点,预判未来业务的发展会出现什么样的痛点,当前的系统架构是否是合适的,如果存在问题,那就需要进行重构了,而业务中间件的设计,就是重构过程中很重要的一步。
下面来说一下系统分析的套路
2.1 系统评价指标的建立
要做一件事儿,我们首先要知道什么是好,什么是不好,所以第一步要建立对于我们系统的评价体系。
image.png
技术方面:吞吐、日常可用性是最常用的两个指标,单位资源下能处理多少业务请求、处理过程中多少是有效处理。
业务方面:开发一个新功能的成本是多少、维护一个老功能的成本是多少,这里可以摆脱当前的系统现状,完美状态下 分别应该需要多少人力,内心建立一个预期。
风险方面:面对极端情况时系统是否可用、部分不可用时是否会造成全局影响、是否存在应对方案
2.2 梳理业务流程 - 整理稳定逻辑、易变逻辑
我们需要熟知面临的业务逻辑,首先把一团业务梳理出具体的大能力,然后梳理出能力中的具体流程,然后拆出流程中的所需的刚性功能点。然后对于我们功能点和具体流程进行分析,看哪些业务逻辑是易变的,哪些业务是稳定的。
拿重业务的CRM系统举例,一个大的CRM范畴内按能力类型大致可以拆分成销售管理、运营管理、营销管理,在此之上具备整体效果、效率分析的能力。
image.png
其中销售管理又可以细拆成“任务下发”、“客户保护”、“合同管理”、“业绩管理”等能n多能力,然后合同管理具有自己的大流程,模版管理、合同申请、签章、审批、履约等等,申请过程具备自己的流程:选择类型、填写内容、签署、邮寄等等,然后每个功能点又具备自身的细分功能点。
其中模版管理是稳定流程,合同审批是易变流程、清分规则是易变逻辑、财务流程是稳定逻辑。
拿营销活动距离也是一样的,要做什么样的活动,活动具体玩法是什么样子、玩法之间的关系是什么样子,玩法内部具备什么样的功能点。
2.3 由业务流程反观功能实现
进行系统架构的分析,对于当前系统进行新增功能开发、老功能变更时的方案进行预演,看功能变更过程中是否存在困难,然后用上面的系统评价指标进行评价。处理之外也需要对系统的功能进行技术方面的指标分析,看一下整体的吞吐、可用性。
image.png
还是上面的例子,比如更改客户合同部分功能,有没有收到其他功能的阻碍,新增一种清分规则是否要编写代码,新增一个签署方式签署管理是大规模变更还是插拔式开发,履约流程新增一个节点是不是整个流程都要变动,系统增加了客户保护功能对其他大功能影响是否巨大。
2.4 寻找原因
看到问题之后需要反观下我们的系统到底因为什么变成了这样:
无脑copy导致的重复代码太多?
为了省事儿的不合理复用?
大量临时代码的技术债?
case by case的功能设计?
模型定义不合理?
功能边界不清晰?
功能间的交互关系设计混乱?
找到具体原因之后,我们可以选择对于模型进行重新的定义、架构的重构、垃圾的代码的重构等等操作。
在设计的过程中,就可以对于业务下的通用功能进行抽象来构建业务中间件,结合现有技术或思想解决一类痛点问题来构建业务中间件,再或者包装一下现成的一些技术中间件使其具备业务属性从而更加高效 来构建业务中间件。通过构建这些业务领域下的中间件使我们的架构更加清晰、痛点问题得到集中解决,从而使业务功能开发和维护更加简单。
3 避免大而全等误区
业务中间的设计并不是架构设计中的银弹,它只是在复杂业务下的一种相对有效的解决思路,而且一个业务中间件往往只能解决一类问题或者某一个特定痛点,不要妄想写一个非常强大的中间件能解决一切痛点问题,术业有专攻才是正道。
4 经典思路
说几个常用的设计思路,可以作为痛点的切入点来处理,整体来说就是关注变化、关注公共处理、关注联系。
4.1 边车模式 - 平面思想
边车指的通常就是摩托车的“跨斗”,边车模式正如名字那样,给我们的功能或者系统上一个跨斗,这是一个经典的平面思想,面向切面的思路去解决分布式应用构建过程中通用代码活动通用流程的问题,跟代码开发过程中的AOP的处理思想类似,只是处理的维度不同罢了。
image.png
最常见的边车模式的使用是微服务中的服务网格,将监控、流量调度、数据上报等一系列每个业务逻辑底层交互细节及公用agent收敛,给业务业务开发装了一跨斗,我们只需要专注业务逻辑处理即可。
在业务中间件实践上也是类似的,系统交互流量调度可以这么做、信息流调度 资金流调度这些理论上都是可行的,能把监控拉出来在切面里处理,那触达等附加逻辑也是可以同样方式处理的,能抽离处理认证鉴权 节点中的流转许可也是同样的道理。
image.png
我们只开发业务处理的单元能力,将单元能力之间的串联逻辑释放出来,每个单元能力挂一个边车,由边车统一处理串联逻辑、由边车统一处理单元的公共触达等等,并且边车很大一个优势在于我们可以有选择性的给我们想要的服务装边车。
4.2 is-a思想的放大
is-a的思想并不只是我们面向对象编程的可以用,在做中间件设计的时候也是一个经典的思路,适当的从具体应用向上泛化拿到本质。
image.png
比如我们需要多种对象存储但是显示的感知各类存储引擎的操作细节太过麻烦,就可以抽象一个对象存储的中间件,只需要操作这个中间件就可以了,具体的访问细节、引擎的操作细节交给中间件去处理就好啦,阿里tair(集成redis、levelDB等)就是这种实现思路。
在业务上的抽象设计也是相似的,push、消息、私信、弹窗、toast 本质上都属于对于用户的触达或反馈,所以我们业务系统中只需要感知触达就好了,具体操作细节和路由处理等等交给中间件去解决。
一些代理模式本质上也是这种思想的放大,正向代理、反向代理不同的角度出发去隐藏实现细节,然后在代理中做适配工作。
4.3 稳定层与变化层分离
稳定层与变化层分离 有两个维度一个是易变的业务逻辑同稳定的业务逻辑相互分离、另一个是将代码功能维度和具体业务处理相分离。
第一个维度相对简单,我们可以利用策略模式等将易变逻辑变得可插拔即可,但本质上我们存在逻辑新增或者变更时依旧是需要写代码(但是这种方式依旧是隔离易变逻辑的常用思路),所以这里推荐的是代码功能维度和具体业务处理相分离。有几种处理思路大家可以根据当前的业务现状做判断,选择的时候一定要注意投入产出比。
image.png
首先第一阶段是纯粹的写代码,新增和变更时都需要改代码,DB + 业务代码就是这种模式
第二阶段是固定流程 + 业务配置 + 基础能力,新增处理逻辑时需要新增基础能力的开发和调度配置,我们的常见业务系统就是这样的事项模式。
第三阶段是固定流程 + 动态规则 + 基础能力,新增处理逻辑时只需要增加决策规则就可以了 无需代码开发,但是处理流程发生变化依旧需要写代码,风控决策、推荐、资金流调拨、广告这类系统通常是这种处理模式,经典的柔性控制的思路。
第四阶段低码规则 + 基础能力,低码方案生成代码、Faas提供原子基础能力,当前低码建站等平台就是这种模式。
第五阶段 纯粹代码生成的方案,这块还属于行业探索的阶段,到底是AI写码还是如何大家可以畅想一下。
image.png
上面这么说有点抽象,举几个例子:
整个发展过程中善用的工具比如决策引擎、规则引擎、流程引擎 就是将业务规则同代码处理逻辑剥离最好用的工具。
比如说:
1、营销活动中给用户的激励,可以使用规则引擎来动态定价。
2、任务下发中给用户下发任务的决策可以使用决策引擎来决定是否下发,或者直接人群的圈定。
3、B端各类处理流程,可以使用流程引擎进行进行动态流程的编排。
4、风控系统中的拦截规则、推荐系统中match 规则、广告系统中的出价规则和match规则
5、资金账务系统中的资金流流转规则
6、游戏引擎中的脚本规则插入、地图引擎中的规则嵌入等等,都是类似的实现思路。
我们再利用这些能力构建公用工具的过程本质就是业务中间件实现的过程。
4.4 领域内设计 - 更多的业务属性
再就是解决一类特定的痛点问题的方案,使我们的技术中间件具备业务属性,然后专注于某一业务领域的特定问题解决。
image.png
比如说:
1、我们的存储,mysql直接支持各类账务可以做,但是每次共同的逻辑都比较多,账务的逻辑都是相对统一的,可以直接开发一个高可用的通用账务存储。
2、依旧是存储,要用于支持各类营销活动,中间涉及大量的库存控制等逻辑,要用于应对秒杀等场景,就直接开发一个库存存储即可。
3、还有事务型mq 都是结合具体的业务特点进行具像化后的设计思路。
4、对于上下文来说,就可以结合各类存储做一个具有业务意义的上下文存储能力。
类似的思路还有很多结合业务特点去做就可以啦。
4.5 总线思想
总线思想想必大家是一点都不陌生,当事件种类特别多、事件之间的交互关系非常复杂的时候,总线思想是最常用的解决思路之一。
如果不清楚总线思想中的落地,可以看下操作系统中的三大总线:控制总线、地址总线、数据总线,也可以看下SOA中的事件总线的设计实现。
需要注意就是我们设计的具备业务属性的总线,并不是常用基础包中解决消息的事件总线。主要提供的事件的动态关联分发的能力,提供了标准的协议定义,用于解决特定业务场景下的复杂事件交互关系。
image.png
这里就不再举具体例子了,前面提到的活动事件总线就是具体的实践落地。
4.6 总结一下
善用设计理论,比如常见的架构设计思想、面向对象思想,熟知业务及业务对应的未来发展。
很多时候一个业务中间件的设计和落地的过程往往是多种设计思想结合的产物,比如之前提到的事件总线、消息总线、决策引擎、规则引擎等等,无招胜有招,只要知识储备足够多、对业务和系统足够了解 就一定能发现其中的问题并能够完成重构优化,以此构成提效。
拿上述的事件总线来看:建立总线之后就可以动态的处理订阅或者触发关系,关系之间又可以利用决策引擎进行动态决策,流转关系就构成了业务流程引擎,然后利用边车模式挂到需要的服务上去即可。
5.举几个例子
前面提到了n多例子,下面再重复的看下:
1、规则决策引擎该怎么设计?
2、业务事件总线该怎么设计?
3、高可用账务中间件该怎么设计?
4、动态激励定价中间件该怎么设计?
5、效果数据反哺该怎么设计?