^_^ 3 分钟掌握业务中台设计技巧

业务中台的名气震天响,听得我耳朵都快起茧子了。在网上关于业务中台架构设计的文章有很多,但是只有很少一部分内容能看懂。不是因为大家理解水平低,原因在于业务中台有大量的业务背景,没有业务经验的人很难深入理解对应业务的中台架构设计。

因为我在会员中台遇到的某个业务场景比较简单,所以我决定深入浅出聊聊。

第一个业务背景和解决方案

我所在的会员中台负责各个产品形态的会员,例如 XX买药的会员,XX外卖的会员,XX 卖酒的会员。会员业务需要用户支付,需要经过订单系统,用户支付完成后,系统会给用户履约------------发放各类会员权益。履约完成并不是会员售卖的终点,系统还需要财务结算。

会员中台需要一个胶水层对接财务结算系统。为什么是胶水层呢?因为底层的财务结算系统也是中台,它们需要对接各种上游系统,为了避免适配别人的系统,它们已经抽象了通用的交互协议。底层已经通用了,只得上游系统(也就是我们会员中台)做胶水层------------负责粘结对接两个系统。

在会员售卖场景,结算会关注会员订单的多个状态,会员中台的胶水层负责把结算关注的数据传输给它们。关注的状态包括购买(支付)完成、履约完成、退款完成、资产冻结完成、资产过期等。值得一提的是,不同的会员业务的结算方案不同,每个会员感知一部分状态,并不是每个会员都需要感知以上所有的状态。例如 XX买酒的会员只关注履约完成和退款完成两个状态,而XX外卖会员最复杂,它关注以上所有的状态。

第一个知识点完成梳理

不同种类会员的结算方案不同,结算时关注订单状态也各有不同。研发听着就行,结算产品和财务会计他们说啥就是啥。

普通解决思路

管你什么结算方案,你关注啥需要啥,我重新写一个流程就行。"中中中,要啥数据给你啥",这么简单,还需要思考?

中台的解决思路

既然结算系统关注 5 个状态,胶水层需要先对接 5 个状态。

某个会员业务是否关注某个状态 这是由产品决定的。我是程序员,我决定 把匹配规则写到配置中, biz(业务线) 和 status(状态) 两个字段 建立一个映射表。

例如处理履约完成事件时,先查询映射表,看看这个事件对应的哪个业务线,然后查询对应的映射表 履约状态和业务线 A 是否匹配,不匹配则丢弃即可。

要说明的是,这个映射表不是 Map, 而是一个 List。因为一个业务线关注多个状态,一个状态也被多个业务线关注着,使用List 比 Map 更合适。规则匹配时:循环遍历所有的配置数据,纯内存操作,速度极快。

第二个业务背景和解决方案

结算系统在每个状态事件,需要很多数据。主要有三大类

  1. 订单类数据,包括 订单 id、用户 id、订单类型、订单实付金额、订单下单/退款时间、退款金额等。

  2. 资产类数据,包括 会员生效时间、会员过期时间、会员唯一凭证、会员发放红包列表。

  3. 结算类数据,包括 会员产品类型,会员资产类型,结算事件类型、结算动作类型、会员收入归属方。

胶水层需要在履约完成这个状态事件中,汇总订单数据和会员履约的资产数据,把这些数据映射成结算指定的格式,这也是胶水层的本职工作。

虽然以上数据有很多,但是大部分数据取值逻辑比较简单,例如订单 id、订单实付金额和退款金额都明确的字段一一对应,各业务线没有差异化。

真正有差异性的是资产类数据和结算类数据。

  1. 不同的业务线查询会员红包列表逻辑不一样。
  2. 有的业务线需要会员红包数据,有的不需要这个数据。
  3. 结算类数据包括产品类型、资产类型,各个业务线都有对应的值,取值有差异化。

此外,会员履约时,系统给用户发放很多种权益资产,结算只关注最核心的几个资产。系统中使用 产品类型和会员权益类型区分不同的权益资产。

第二个业务背景补充完成。

普通的解决思路

你关注啥需要啥,我重新写一个流程就行。"中中中,要啥数据给你啥",这么简单,还需要思考?

普通的解决思路------------只要新来一个业务,就重新写一遍。大家不要嘲笑这种方式,在会员中台长达三年的时间里,我们一直践行这个原则------------能用就行。

看似会员中台,在很多模块就是重写一遍。把多个业务线的代码写在一个工程里,就是会员中台。

但是我被领导卷到了。

领导问我:"为什么极度相似的业务,还需要重新开发代码呢?"

"重新写一遍也不复杂,我一天就写完了,没啥............",我还想说没啥难度。

话音未落,领导就打断我:"中台的价值在哪里?"。

我也说不好中台的价值,我想回答领导:"你觉得呢?",但我怕这么说以后,被踹出会议室。沉默一会儿,就跟领导说:我还没想好,我再想想这个问题------------如何避免重复开发......

中台的解决思路

总结第二个业务背景

  1. 结算系统关注核心的权益资产,需要使用产品类型和权益类型来区分。

  2. 结算类数据需要映射。根据不同的权益资产映射为不同的结算类型。

胶水层负责把会员履约数据映射为结算数据。

我的思路是,首先提炼出映射规则,然后将映射规则放到配置数据中,就能避免新来业务线,代码重复开发的问题。

我定义了一个映射规则模型

Java 复制代码
public class Rule {

    public int biz;               // 业务线
    
    public int status;            //业务状态
    
    public int productType;       //业务产品类型
    
    public int rightType;         //业务权益类型
    
    public int orderType;         //业务订单类型
    
    public int settleEventType;   //结算事件类型
    
    public int settleOrderType;   //结算订单类型
    
    public int settleProductType; //结算产品类型
    
    public int settleAssetType;   //结算资产类型
    
    public int settleAccountId;   //收入归属账户
    
    public CouponQueryStrategy strategy; //红包查询策略
}

当胶水层需要处理XX外卖会员的履约完成事件时

  1. 查询该业务履约状态的规则列表。使用字段 biz 和 status。
  2. 过滤规则,使用会员资产数据。根据权益资产类型过滤规则,使用字段 productType 和 rightType。
  3. 过滤订单类型。使用字段 orderType 过滤业务规则。(有多种订单类型,例如兑换码兑换、主页购买、随外卖实物单捆绑售卖,不同订单类型处理逻辑不同,需要区分)

经过前三步以后,就能匹配该事件对应的规则。 如果未匹配成功,则丢弃这个事件即可。

构建结算数据时,像订单 id、用户 id 和实付金额退款金额等明确取值的字段 正常构建即可。

针对有差异性的数据,例如资产类型和收入归属账户等,从规则中取值即可。

前面提到:不同的业务线获取红包列表的方式不同,可以在规则中配置策略接口,不同的规则提供实现类即可,通用流程层代码调用具体策略类即可。

使用什么方式配置 Rule

以上配置数据放到哪里合适呢?我觉得有四种实现方案,大家选择适合自己的就行

1. 放到代码里

RuleService 中直接写对应的规则就行;例如

Java 复制代码
List<Rule> rules = Lists.newArrayList();

@PostConstruct
public void init(){
    Rule rule1 = new Rule();
    ............... 构建 rule 1;
    rules.add(rule1);
   
    Rule rule2 = new Rule();
    ............... 构建 rule 2;
    rules.add(rule2);
}

2. 使用 Spring @Bean 注解

通过 Spring @Bean 注解可以把 Rule 注册进 Spring 中,使用 Autowired 可以装配所有的 Rule;

Java 复制代码
@Autowired()
List<Rule> rules;

@Bean
public Rule xxxPerformRule(){
     Rule rule = new Rule();
    ............... 构建 rule ;
    return rule;
}

3. 使用 Spring XML 配置

刚才那两种办法不够中台,新业务来了还需要开发代码。使用 XML 也能配置 Rule,写 XML 不算写代码 ^_^

在 Spring 的 XML 中配置 Rule 就像配置一个普通的 Bean。并且 Spring 提供了非常强大的功能,例如可以配置枚举值,引用其他 Bean,配置 Map、配置 List/Set等。 我们项目中配置数据就放在了 Spring XML中。 不过这个方案的缺点是依然需要上线发布......

XML 复制代码
<Bean name="xxxPerformRule" class="com.xxxxx.Rule">
    <property name="biz" value="WM"  /> 
    <property name="status" value="PERFORM"/>
    ..................
</Bean>

4. 将配置数据放到配置中心

配置中心:例如携程 Apollo携程框架部门研发的开源配置管理中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端

将配置放到配置中心可以实时生效,无需代码上线就能新增配置。

不过设想一下:新增一个业务线,真的不需要开发代码吗?这是最理想的情况,绝大部分情况需要开发代码和上线。所以大部分业务场景,不需要放到配置中心。

其他的方案包括,放到数据库里,或者提供可视化页面都可以,大家根据实际的情况自行选择即可。

总结

  1. 中台项目中 如果遇到不同的业务线需要处理不同的数据的场景,可以把匹配逻辑放到配置数据中

  2. 中台项目中国遇到 不同的业务线数据映射规则不同的场景,可以把映射规则放到配置数据中。

  3. 配置数据推荐使用 Spring XML 配置。

相关推荐
齐 飞1 小时前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb
LunarCod1 小时前
WorkFlow源码剖析——Communicator之TCPServer(中)
后端·workflow·c/c++·网络框架·源码剖析·高性能高并发
码农派大星。2 小时前
Spring Boot 配置文件
java·spring boot·后端
杜杜的man3 小时前
【go从零单排】go中的结构体struct和method
开发语言·后端·golang
幼儿园老大*3 小时前
走进 Go 语言基础语法
开发语言·后端·学习·golang·go
llllinuuu3 小时前
Go语言结构体、方法与接口
开发语言·后端·golang
cookies_s_s3 小时前
Golang--协程和管道
开发语言·后端·golang
为什么这亚子3 小时前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算
想进大厂的小王3 小时前
项目架构介绍以及Spring cloud、redis、mq 等组件的基本认识
redis·分布式·后端·spring cloud·微服务·架构
customer084 小时前
【开源免费】基于SpringBoot+Vue.JS医院管理系统(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·开源·intellij-idea