首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >记一次中台建设的过程及心得

记一次中台建设的过程及心得

作者头像
烟雨平生
发布2023-03-07 13:58:12
发布2023-03-07 13:58:12
5020
举报
文章被收录于专栏:数字化之路数字化之路

设计系统的架构受制于产生这些设计的组织的沟通结构。

背景

目前在一家ToB的公司做研发,公司希望通过数字化来提升整个工业品行业的效率。公司的系统是围绕SAP系统进行建设,简单可总结为SAP+外围适配系统+前台系统。

业界建设中台的原因

前台与后台解决的问题不同,后台管理的往往是企业的关键核心数据,考虑到企业安全、审计、合规、法律等限制,这样的系统也往往⽆法被前台系统直接使用,或是受到各类限制⽆法快速变化,不能⽀持前台快速的业务创新需求。 中台就像是在前台与后台之间添加的⼀组“变速齿轮”,将前台与后台的速率进行匹配,是前台与后台的桥梁和润滑剂。它为前台而生,易于前台使用,将后台资源顺滑地通过前台导流向用户,支撑企业更好地响应用户

在讲中台之前,先定义下前台和后台分别指什么。

前台:

由各类前台系统组成的前端业务平台。每个前台系统都是一个用户触点,大多是企业最终用户直接使用的系统,是企业与最终用户的交点。例如用户直接使用的网站、手机 App、微信公众号、小程序等都属于前台范畴。

后台:

由后台系统组成的后端支撑平台。每个后台系统一般管理了企业的一类核心资源(数据 + 计算),例如财务系统、产品系统、客户管理系统、仓库物流管理系统等,这类系统构成了企业的后台。(在和很多互联网的朋友聊过之后,在互联网企业很多并没有后台的概念,更多直接使用平台的概念,例如分为前台层和平台层,但位置和作用与传统企业里的后台相似,我这里直接统一使用后台这个概念来代表。) 定义了前台和后台,我们再回过头来看企业为什么要建中台这个问题

我们看到很多企业的后台,在创建之初的目标,并不是主要服务于前台系统的业务创新,而更多的是为了实现后端资源的电子化管理,解决企业管理的效率问题。这类系统要不就是当年花大价钱采购的套装软件,需要每年支付大量的服务费,并且版本有的也已经非常老旧了,定制化困难;要不就是花大价钱自建,年久失修,一身的补丁,同样变更困难,基本改不动了,也是企业所谓的“遗留系统”的重灾区。 可以这么说,大多数企业已有的后台,要么前台根本就用不了,要么不好用,要么变更速度就根本跟不上前台业务发展的节奏总结下来就两个字“慢”和“贵”,对业务的响应慢,动不动改个小功能就还要花一大笔钱。 有人会说了,你不能拿遗留系统说事儿啊,我们可以新建后台系统啊,整个 2.0,问题不就解决了? 这是一种解决问题的思路,不过就算是新建的后台系统,因为后台管理的往往是企业的关键核心数据,考虑到企业安全、审计、合规、法律等限制,这样的系统也往往⽆法被前台系统直接使用,或是受到各类限制⽆法快速变化,不能⽀持前台快速的业务创新需求。 此时的前台和后台就像是两个不同转速的齿轮,前台由于要快速响应前端用户的需求,讲究的是快速迭代创新,所以要求转速越快越好;而后台由于面对的是相对稳定的企业核心后端资源,而且往往系统陈旧复杂,甚至还受到法律法规、审计等相关合规约束,一般是追求稳定至上,越稳定越好, 转速也自然是越慢越安全。 所以,随着企业业务的不断发展,这种“前台 + 后台”的齿轮速率“匹配失衡”的问题就逐步显现出来了。 企业业务不断发展壮大,后台修改的成本和风险越来越⾼,这就驱使我们尽量保持后台系统的稳定性,但同时还要响应用户持续不断的需求,怎么办?最自然的就是将大量的业务逻辑(业务能力)直接塞到前台系统中,因为前台离用户近,响应也相对快。 但是这样也是有代价的,这样的后果就是引入重复,同时还导致前台系统不断膨胀,变得臃肿,形成了一个个大泥球的“烟囱式单体应用”。这个局面的结果就是,前台系统的“用户响应力”被渐渐拖垮,用户满意度逐渐降低,企业竞争力也随之不断下降

有了这层“中台”,我们既可以将早已臃肿不堪的前台系统中稳定通用的业务能力“沉降”到中台层,为前台减肥,恢复前台的响应力;又可以将后台系统中需要频繁变化或是需要被前台直接使用的业务能力“提取”到中台层,赋予这些业务能力更强的灵活度和更低的变更成本;或者干脆直接对于后台进行中台化改造,通过配置化、自助化、白屏化等形式为后台加速,从而为前台提供更强大、更迅捷、更易用的“能力炮火”支援。

中台就像是在前台与后台之间添加的⼀组“变速齿轮”,将前台与后台的速率进行匹配,是前台与后台的桥梁和润滑剂。它为前台而生,易于前台使用,将后台资源顺滑地通过前台导流向用户,支撑企业更好地响应用户

在最后,为了让我们能轻易记住中台的特性,并能用它来快速判断一个所谓的中台是不是满足我对于中台的理解,需要一把尺子:中台是企业级能力复用平台

听过多遍,感觉不错,推荐

客户中心的现状

目标

客户中心与其它业务系统解耦:

1、数据架构解耦。不再有其它业务系统直接连接客户中心的库进行数据操作。

2、数据安全。统一更新客户中心数据的入口,确保客户中心任何的数据变更都能溯源。

3、一站式。在一个前端入口即可完成所有操作 4、高内聚低耦合。独立开发、独立的部署、独立扩缩容 5、更快的迭代。轻装上阵,快速响应前台

迁移方案

方案1:弯道超车,一步到位。按照业界最前沿的理论和实践建设中台。
代码语言:javascript
复制
1.1 好处:起点高    
      1.1.1 抽取更合适的业务模型,更容易适配各种业务场景;   
      1.1.2 构建更合适的数据模型,更好地推进数字化战略;   
1.2 坏处:耗时,耗时    
      1.2.1 需要识别各个业务场景;   
      1.2.1 前台系统需要花更多的时间来适配新的服务;   
方案2:小步快走,先独立,再发展。按高内聚低耦合的标准,先实现代码层面客户中心的独立,再实现数据层面的独立,后面在根据业务的特征不断迭代
代码语言:javascript
复制
2.1 好处:迭代思维,小步快走     
      2.1.1 之前业务方不需要做太多的调整,即可完成适配     
      2.1.2 根据业务方的痛点,结合业务场景,提供可复用的企业级服务     
2.2 坏处:只是迁移    
      2.2.1 迁移出现的是一个微服务。并不严格意义上的中台     
      2.2.2 整体平移,这种情况很容易产生技术债,譬如重复、结构不合理的问题    

实际落地时使用了方案2。

因为有另外一个中台是按方案1进行,建设周期过程中识别到的复杂度及工期超过了预期,项目延期的风险很大;

另一方面客户中心投入的人力有限。

落地篇

A project is a temporary endeavor undertaken to create a unique product,service , or result. 项目是为创造独特的产品、服务或成果而进行的临时性工作。

客户中心是按项目的方式进行管理的。具体落地是使用了工具PDCA:

1. 拆解需要做的工作

1.1 客户中心涉及到的数据流有4类

1.1.1 提供前台的数据分发服务 1.1.1.1 接口 1.1.1.2 MQ消息 1.1.2 与销售易【一个CRM系统】进行双向同步 1.1.3 推送数据到SAP 1.1.4 客户中心后台管理涉及到的页面和接口

2. 制定计划

细节略。

要点有以下两个:

2.1 依赖第三方的,优先级高。 譬如提供给前台系统的接口,需要兄弟团队排期 2.2 适配好前、后端、测试的工作节奏,以稀有资源的节奏来排计划。 譬如前端同时参与多个项目的前端需求,如果客户中心这边没有事情做,就去做别的项目的活,这种时断时续的情况,让前端同学处于不停切换上下文中,在效率上会受到影响。测试同学也一样。

3. 执行

细节略。

识别到新的问题及解决办法:

3.1 业务团队不知道调了客户中心那些接口 3.1.1 每个团队都有一些老项目。稳定且不重要,也没有几个人知道这个项目的存在 3.1.2 遗漏。迁漏了。因为新老接口提供的数据一致,不容易识别 3.2 解决办法及踩过的坑: 3.2.1 通过arms【阿里提供的监控服务】查看是否有流量进来。 此处有坑:超过一个时间范围,在arms查询到的结果就不准确了。即“在两个月内,这个接口是否被调用”arms上的查询结果是错误的。 3.2.2 通过网关日志查看一个接口是否仍然在被使用。只有调用方的IP,需要运维支持才能确定是那个服务

4. 检查执行效果并总结改进方向

细节略。

4.1 协调好业务需求和迁移计划的关系。 抽出可复用的组件,加快交付速度,让业务需求的交付速度大于产品和业务方的验收速度【团队的同学很给力】。 4.2 缩短客户中心支撑、答疑工作占用的时间。 及时fix业务团队、业务方反馈的bug,反馈一个解决一个。 从刚接手时的平时10-15个/周,缩短的3-5个/周,并且现在大多是澄清一下,客户中心的服务并没有问题。 高频出现的问题大多是由于系统是个黑盒,无法观测到接口内部数据状态的流转,以及有脏数据导致前台系统一下子不知道怎么办了,就直接报错了,譬如客户名称有两个一样的,按照业务上的定义客户名称是唯一的。

踩的坑及经验总结

迁移过程中遇到的问题以及在中台建设中的一些方向:

  1. 企业级的接口访问权限治理。 要基于前台的用户来进行权限控制。这样也能很方便地知道,这个接口服务了那些业务方。 接口访问权限分级,中台服务面向的是各个前台,各个前台是一个租户。
  2. 服务治理: 2.1 要按业务场景来提供服务。目前的服务是按数据进行提供的。 按数据提供接口的特征:把表中所有字段都返回。 按场景提供接口:根据特定的场景,只返回这个场景需要的数据。 什么是场景: 譬如页面上根据 客户名称来筛选客户的; 譬如 根据客户id批量换客户名称 2.2 没有看到是那个用户调用的。 造成的问题,看到接口被调用,无法确定是那个服务调用的。
  3. 领域语言没有统一: 同一个业务标识没有统一的口径,协同成本比较高。 譬如:下面这四个名词表示的是相同的业务含义: 款期【业务方的叫法】、 客户账期【别的团队的叫法】、 付款条款【客户中心系统中的描述】、 付款条件【销售易系统中的描述】
  4. 数据治理: 4.1 脏数据。譬如客户名有重复,从业务模型来看,是不能有重复的。 4.2 与销售易系统双向同步有字段遗漏 4.3 与销售易系统双向同步没有处理删除场景
  5. 缓存架构升级 5.1 现状:目前使用了本地缓存。 缓存一致性是基于RabbitMq的临时队列来实现。变化时向各个应用通知变更,然后各个应用更新本地缓存。公司计划把RabbitMQ替换成RocketMQ,这个机制就受到影响。
代码语言:javascript
复制
    /**
     * 业务数据1缓存广播交换机,会自动删除
     *
     * @return 广播交换机
     */
    @Bean
    FanoutExchange localCacheConsistencyExchange() {
        return new FanoutExchange("BIZ1_LOCAL_CACHE_EXCHANGE", true, true);
    }

    /**
     * 业务数据1缓存队列,会自动删除
     *
     * @return 队列
     */
    @Bean
    public Queue localCacheConsistencyQueue() {
        return new Queue(UUID.randomUUID().toString() + "服务主机名+IP", true, true, true);
    }
代码语言:javascript
复制
 /**
* Construct a new queue, given a name, durability, exclusive and auto-delete flags.
   * @param name the name of the queue.
   * @param durable true if we are declaring a durable queue (the queue will survive a server restart)
   * @param exclusive true if we are declaring an exclusive queue (the queue will only be used by the declarer's
   * connection)
   * @param autoDelete true if the server should delete the queue when it is no longer in use
   */
  public Queue(String name, boolean durable, boolean exclusive, boolean autoDelete) {
          this(name, durable, exclusive, autoDelete, null);
}

5.2 升级:

5.2.1 本地缓存的属性出现变更时,使用Rocket的广播模式来通知各个实例进行更新本地缓存的工作 5.2.2 去掉非必需的本地缓存。譬如有个业务数据只有50多条数据,仍然使用了本地缓存。老逻辑中并没有确定这组数据的一致,导致一有变更,就需要发版解决。 5.2.3 在合适的场景使用Redis。譬如KV结构的数据,可以切换成Redis,对数据库字段模糊的场景,仍然使用本地缓存EhCache。

代码语言:javascript
复制
 /**
  * 从缓存中查询对应字段的信息--模糊查询
  * @param attrName
  * @param param
  * @return
  */
 public List<ContactBO> searchByAttrFullLike(String attrName, String queryParam) {
     Cache contactCache = CacheFactory.cacheManager.getCache(CacheConfig.CONTACT_BASIC_CACHE_NAME);
     Attribute<String> attribute = contactCache.getSearchAttribute(attrName);
     Query query = contactCache.createQuery();
     query.includeAttribute(attribute).includeValues();
     query.addCriteria(attribute.ilike("*" + queryParam + "*"));
     Results result = query.execute();
     if (result != null && result.size() > 0) {
         return result.all().stream().map(e -> (ContactBO) e.getValue()).collect(Collectors.toList());
     } else {
         return Collections.emptyList();
     }
 }
  1. 继续加强可观测性的投入 。 “监控告诉我们系统的哪些部分是工作的。可观测性告诉我们那里为什么不工作了。” 就客户中心这个中台而言,提供的OpenApi,可观测性就是打日志。特别是业务出现异常时的相关的数据及上下文信息。 因为阿里的arms上只能看到请求,无法提供根据查询报文来锁定是那个请求,对锁定并解决业务问题帮忙并不大。

团队小伙伴也有觉得这个活没有技术含量,有些情绪; 周会上也有同学觉得用一个高大上的词来包装打日志有些浮夸。 不过黑猫白猫,管用的就是好猫。 打日志这个操作是刚入行的同学都会的,但是在那个地方打日志、日志中包含那些内容,这些是需要比较深的业务知识,及排查问题的经验才能打好日志。既不能没有日志,两眼一抹黑;也不能因为打的日志过多,导致扰乱了关键点,影响排查问题,譬如一个接口打了100多条日志,翻了好几页,也没找到关键的点。

6.1 将客户中心的所有应用中都增加arm中的traceId。通过TraceId可以串联起一个请求的所有日志

6.2 打印关键日志。日志需要中需要有时间、操作帐户、请求报文、执行结果。执行流程出现异常时或关键分支出现切换时要包含上下文日志。

团队的日志打印规范,欢迎拍砖

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 的数字化之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 业界建设中台的原因
    • 前台:
    • 后台:
  • 客户中心的现状
  • 迁移方案
  • 踩的坑及经验总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档