系统架构系列之业务架构实战

家电修理 2023-07-16 19:17www.caominkang.com电器维修

一、什么是业务架构

系统架构的方法系统性思考、分解、抽象、模式,这是总的纲要,针对不同类型的业务架构,要结合本身的特性再加以细化。

业务架构是系统架构的一种,那什么是业务架构呢?业务在百科中的定义是" 涉及一个以上组织,按某一共同的目标、通过信息交换实现的一系列过程,其中每个过程都有明确的目的,并延续一段时间 "。从这句话可以看到几个关键词组织、目标、过程,下面仔细分析这几个关键词的含义。

  • 组织业务涉及到的人或者组织,这个比较好理解,一项业务应该由多个人来完成,如销售、财务、产品、研发、售后等。
  • 目标这是做这项业务的目的和价值,换言之,为什么做这项业务,做好这项业务要达到的目标是什么。
  • 过程过程就是业务过程,一项业务由多个过程组成,如优惠券业务,它的过程是建券、发券、用券、退券。

上面这样的描述可能比较空洞,与我们平时接触的不匹配,再继续提炼出重要信息。

  • 利益相关者这个是从 " 组织 " 和 " 目标 " 中推导出来的,业务的受益方是谁,为什么要做这个业务,肯定有受益的群体,否则没有市场。如优惠券的利益相关者有用户、商户、公司,因为用户下单可以使用优惠券、商户可以吸引更多的客户来消费、公司的GMV就上升了。

  • 业务流程: 这个是从过程推导出来的,并且这个业务流程是固定的 (至少一段时间内)。这里的业务流程是大的流程,每个流程都会再往下分解成子流程,如优惠券中的发券,它会有一系列子流程,如发放规则检验、风控安全等。

综上,到这里,也可以用一个公式来定义业务架构,业务架构 = 业务目标 + 业务流程 + 业务要素,这和系统架构的定义非常相似,只不过是实例化了而已。从业务架构的公式中,最重要的是识别出业务流程和业务流程中包含的业务要素,换个角度来看就是业务要素与业务要素之间的关系,这些关系组成了整个业务。

二、业务架构的特性

已经知道了业务架构是什么,接下来就讨论业务架构的特性,通过特性基本上就知道业务架构的大体框架。笔者通过 x、y 数轴加以说明,因为业务要体现出业务流程的流动性和业务的层次性,下面就说明这两个特性

  • 业务的流动性其实这是业务生命周期的体现,从产生、拥用、使用可以看出业务的流动,这是横向的。

  • 业务的层次性笔者一般习惯用场景层、产品功能层、领域模型层、依赖层来画业务架构图,这是纵向的。场景层依赖下面的产品功能层,多个场景很有可能对应一个产品功能,产品的功能又是由领域模型来支撑的。

三、业务架构的方法

业务架构的方法还是从系统性思考、分解、抽象、模式这四点具体说明。

  • 系统性思考站在业务的角度,分析业务与业务之间的关联性,如优惠券业务,它就涉及到人群选择、风控安全、活动、会场、优惠、交易、凭证等,思考系统之间的交互和依赖关系,以及依赖系统要提供的哪些能力。

  • 分解系统性思考让我们的目光放得更广,整体上考虑整个业务的运转,此时还没有想业务的具体流程,只是知道有,并不深入考虑如何做。分解就不一样,它聚焦的是业务本身是如何运转的,一般业务由几个主要的流程组成的,每个流程又能往下继续分解出细的流程,分解的目的是为了找出业务的要素,此时的元素都是孤零零的。

  • 抽象分解不是我们的目的,通过分解找出的业务要素,此时要经过一定的抽象才能形成我们的领域对象,因为分解找到的业务要素很多是可以合并归类的,这样就大在减少了业务要素,也降低了理解的复杂度。

  • 模式通过业务架构的特性,按照场景层、产品功能层、领域模型层、依赖层这四层画出业务架构图。

有的时候在想,并不是业务架构难搞,只是我们并没有像追求技术那样投入时间研究业务架构,可以不断运用上面的方法,结合自己的理解和扩展,多去实践。

四、通过实例画出业务架构图

下面通过一个电商场景的优惠券业务案例来说明业务架构图是如何画出来的,使用的方法还是上面提到的,通过具体的例子再加以巩固。优惠券对于我们来讲并不陌生,每年的双 11 都有很多优惠券,有满减券、折扣券,优惠券是营销中最常使用的营销抓手。

4.1 优惠券业务愿景和目标

优惠券的业务愿景是让用户可以享受到更多优惠,目标是通过优惠券吸引更多用户加入,从而提升 GMV。

从这里可以看出,愿景一定是为他人着想,绝不是为了公司自己赚钱,而是创造价值的实现双赢,双赢才是最终目标。

4.2 系统性思考优惠券业务

如何进行系统性的思考,笔者建议可以使用反推法,假设已经有了这项业务,它应该是如何运转的、涉及到哪些人,实际上这个过程就是推演的过程,基本上能把整个交互都考虑清楚,业务实现起来基本上没问题。

  • 用户用户有优惠券,下单会使用优惠券,涉及到交易和优惠。
  • 系统涉及到建券、发券、核销券、退券
    • 建券与我们优惠券系统关联最大,也即是我们要做的事。
    • 发券,发给谁呢,肯定不是遍地撒网,现在基本上是精准营销了,要知道哪些用户是活跃用户,所以涉及到算法推荐;除了发给谁是我们关心的,营销还有一个比较核心的点,就是营销模式,你怎么能吸引用户,这就涉及到会场、活动,这些玩法是非常关键的。
    • 核销券优惠券券在什么条件下可用 (满 100 元减 10 块)?订单价格如何计算出来的?
    • 退券退款了,券要不要退回?

所以,经过上面的分析,初步涉及到的业务方就已经出来,此时还只是一个粗略的关系,这个过程可能需要几轮不断的讨论才成型。

4.3 优惠券业务流程

业务流程是客观存在的,而且任何一个业务在一定的时候内应该有一条稳定的业务流程,这个业务流程是符合人的认识的,具有严谨的逻辑性。怎么理解呢?一个业务要运转起来,不可能是一团糟,一定具备流程,而且是人能接收的,否则你设计一个反人类的业务产品出来,注定是失败的。拿优惠券来讲,根据它的生命周期,很容易想到它的主业务流程建券、发券、用券、退券。

4.4 分解和抽象

上面是一个大的流程,还要对各个流程再进一步细分,分解成更小的子流程,每个子流程中包含一系列的步骤,其实这个步骤就是不断深入地过程,对业务的理解也不断加深,多问几个为什么就深入了。

  • 建券这个券包含了哪些内容?
  • 发券给谁发?发券的条件是什么?
  • 用券什么条件下能使用优惠券?用券涉及到哪些过程?
  • 退券什么场景下会退券?

随着深入的过程,整个业务的细节也浮现出来了,现在就是要抓业务要素,这个要素可以通过每个阶段的产物来看。建券的产物是券批次,发券的产物是券实例,用券的产物是用券明细,退券的产物是退券明细。

接下来就是抽象的过程,这个抽象的过程就是对已找出的产物进行抽象。券批次包含券类型和券门槛限制两个重要的信息,用券明细和退券明细统一抽象成券明细,优惠券又与活动强相关,所以也把券活动放进去。

4.5 优惠券业务层次结构

接下来就是画整体的业务架构图了,按照场景层、产品功能层、领域模型层、依赖层来画,画业务架构图要体现两点出来业务流向和产品功能。通过下面的图可以直观地感知业务流向是什么 (即是蓝色区域,建券、发券、用券、退券),通过分层可以清晰地看到可以支持的场景有哪些,场景依赖的产品功能有哪些,业务的领域模型是什么,依赖的业务又有哪些,真正好的图能做到一图胜千言的效果。

笔者喜欢的画法是 " 一主两翼 ",主体的部分就是上面讲的分层,两翼是运营平台和数据平台,这样很直观、简洁。

 

===========

 

一、业务彼此隔离

在较小的公司可能要体现这个没有对应的业务场景,但在大公司中,如果业务是平台型的,承接的业务方较多,业务方之间的需求还不一样时,就体现出了业务与业务之间的隔离。比如,优惠券业务是平台型业务,有多个业务线的业务方接入,它们的诉求也不尽相同有的要实现业务线内不同用户角色的打通 (乘客、司机等)、业务线之间风控策略也不一样、优惠券发放规则也不一样…

业务与业务的隔离需要有一个标识来唯一标志,阿里有的团队叫 bizId,在我们团队是通过 productId(业务线 Id) 来区分。标识说起来简单,但它只是第一步,隔离的表象就是通过业务线来区分。思考一个问题为什么要实现业务之间的彼此隔离?

  • 业务自身需求这个很好理解,不同的业务有自己的特点。
  • 业务之间的互不影响隔离的目的就是为了互不影响,将变化的东西缩小到业务线内,不可能改动一个业务线的需求,结果把其它业务线影响了。
  • 业务的可扩展性平台型的业务有一个最大的特点是要较好地支持可扩展性,往大的方面讲,新接入一条业务线的改动有多大、往小的方面讲,对于某个业务线内的需求改动又是多大,比较好的状态就是具备可配置,稍微配置一下,一个新业务线就接入,这是我们最想看到的结果。

通过 productId(业务线 Id) 这个唯一的业务身份串起整体业务,在业务处理过程中,可以知道这个业务线需要的具体业务策略和处理规则。

结论一业务与业务的隔离体现了业务之间的变化和独立性,所以就产生了业务与技术 (平台) 的隔离。

二、业务与技术 (平台) 的隔离

业务与技术 (平台) 的隔离体现了变与不变的关系,虽然这句话被很多人讲过,但不同的系统实现的策略不一样。平台型业务一般要解决 80% 以上的共性问题,20% 左右通过开放来实现。

业务与技术 (平台) 的隔离不像业务与业务之间的隔离那样,两个业务之间没有交集,业务与技术 (平台) 之间是有交集的,这让人听起来有些蒙,下面细细分析。

  • 不同业务线之间有一条共性的业务流程虽然不同的业务线产品之间有各自不同的点,但它们之间有一个明显共性的业务流程,这个业务流程是业务的生命周期,就好比类与对象之间的关系,本质是同一类事物,不同的对象好比不同的业务线产品,具体的实现上有些差异。在优惠券中,核心的业务流程就四个建券、发券、用券、退券,不管什么业务线接入,它都遵守这条固定流程。

  • 业务变化的是子流程中的内容不同业务线产品的不同之处体现在哪里?体现在业务细节上,这个是变化的,如业务的准入条件不一样、业务规则不一样、有的子流程中某一个处理步骤不需要…,这些是变化的部分,需要把变化的部分抽象出来并封装变化。所以,不变的是业务大流程,变化的是业务实现细节。

  • 业务与技术 (平台) 的隔离理解的二重性有些人理解业务与技术 (平台) 的隔离就是业务的实现不依赖于技术,比如数据要怎样存储?服务治理用什么框架?…这些说的是对的,它本身没有错。而我理解是有两重含义一就是如上面所说的,业务的实现不依赖于具体技术,偏技术选型,这是常识;二是领域层的可扩展性,前 2 项已经说了业务的共性和变化,这个就是体现出应对变化的策略,尽管不同的系统有不同的具体实现,但总的原则是平台要能识别出这些变化,并能应对这些变化。

业务与技术 (平台) 的隔离体现在共性和变化的隔离,把变化的部分告知平台、实现开放出来,所以说它们是有一定交集,这个交集就是应对变化的部分。它涉及到技术方面,所以在技术架构中会单独拿一篇来讲。

结论二业务与技术 (平台) 的隔离主要体现在处理业务的变与不变。

三、业务能力地图

我们有一个体会是开发和产品有时在谈一个需求时,开发用开发的语言、产品用产品的语言,两个很难统一,虽然通过领域建模可以统一认识,随着时间的推进,人员结构也在不断变化,如何快速熟悉业务、统一业务认识是一个问题。

发现通过业务能力地图来表示业务流程,可以减少沟通、统一认识、可视化表示业务产品功能所经过的关键业务路径,这样一个新人进来通过这个业务能力地图就可以知道业务的主流程是什么,产品功能涉及到哪些业务子流程,针对一个需求,开发不需要看代码哪里要修改,很直观地在业务能力地图可以知道本次需求涉及到的改动点,从而提升整体效率。

在做业务能力地图之前是有条件的,否则只是一家之言,有什么意思呢?就是业务已经进行了领域建模,业务产品和开发达成了统一的认识,业务的领域对象有哪些、业务的主流程、子流程有哪些、业务的准入条件、规则判断等,只有这些大家已经统一认识了之后,再通过技术手段把这些信息可视化表示出来就行,否则只会站在开发的角度来理解要表示哪些流程步骤。换言之,业务能力地图中所展示出的节点信息都是开发、产品统一的语言。

业务能力地图是领域模型的进一步扩展和延伸,领域模型偏静态的表达领域对象和领域对象之间的关联关系;而业务能力地图是动态的表达业务执行流程是什么。领域模型是基础,业务能力地图是进一步的扩展,一个表达有什么,一个表达怎么做,一动一静,可以更好的理解业务和业务流程所涉及到的核心步骤。

结论三业务能力地图是在领域模型的基础之上进一步扩展,可视化地表达业务流程。

四、业务 mock 能力

业务 mock 能力是指 mock 用户数据方便排查问题,排查问题的第一步是重现问题,尤其是在端上,可能在某些条件下展示有问题,用测试数据又没有重现这个问题,如何来做呢?可以通过 mock 用户的信息来展示数据,说白了就一句话偷天换月,在最底层的查询时,把用户信息置换掉。举个例子,用户在下单时发现有些优惠券没有展示在列表页中 (实际上是有些优惠券不满足订单条件,如满减券、限门店使用等),用户向客服反映,客服再向技术支持人员反馈,技术支持人员再往具体的开发反馈,这个链路就很长了。如果客服同学使用这项 mock 能力,完全可以通过 mock 用户数据来当前的数据是怎么展示的,再看用户所有优惠券,对比优惠券的限制规则就能知道哪些优惠券不能使用,这样就可以快速响应用户问题。

使用这个 mock 能力时,有一点需要考虑的就是数据安全,并不是所有的行为都可以 mock,一般来讲只有读场景下才能 mock;还有一点需要注意的是全链路 mock 范围,只有在指定的接口上才能 mock,不能直接从导购链路一路往下 mock,只会在最底层的业务接口上进行 mock,否则全链路数据都被置换了。

结论四mock 主要方便问题重现和定位。

五、业务监控

业务监控也是非常重要的一个环节,不同的公司用的方法也不尽相同,也要看业务规模和公司的实际情况,不可能要求所有的公司都使用大数据来分析。根据自己的经历谈谈这块。

小公司直接统计业务数据表,比如之前做过金融,根据还款数据拆分成还款计划,还款计划再生成对应的还款订单,这里面的涉及到的业务数据就比较多,但能够很好地进行监控,当时根据业务数据状态、数量来判断业务是否已经处理完了,通过核对数据看今天的业务执行是不是正确的。这虽然很简单,通过写SQL+ 定时执行 shell 脚本就可以搞定,在业务的初创期它最简单,关键是提炼出监控的指标和维度。

在大公司,通过日志采集、清洗、实时统计,可以看出当前业务的处理情况,有同比、环节的数据,如当前下单率是多少,通过监控这个指标可以看出业务是否正常,如果下单率明显下跌比较厉害,大概率是哪个链路上出了问题。

通过业务监控大盘分别从不同的维度来监控业务运行状况,从而可以分析判断出当前业务是否受影响,帮助开发人员提前发现问题,这一块也涉及到稳定性方面,大公司是非常重视这一块的,阿里双 11 会专门成立稳定性小组,稳定压倒一切。

结论五没有业务监控的系统对业务的运行状况一无所知。

============

一、可扩展的本质是什么?

可扩展的意思是在面对变化时,用最少的代价去实现,平时我们听得最多的是面向抽象 (接口) 编程,如果只是把这里的抽象理解成接口,那么就有些狭隘了,抽象是通式通法,而接口只是其中一个,所以在谈可扩展实现之前一定要讲清楚可扩展的本质是什么,连本质都不知道,怎么提出系统性解决方案。

1.1 扩展的本质

扩展的本质就是占位符,明确告诉你这里被占了,具体谁占了不清楚。那么问题来了占位符到底是什么?它是怎么表达的?又要如何实现的?如果可以把这三个问题理清楚,就可以想到很多可扩展性方案,而不再是单一的面向接口编程。

  • 占位符到底是什么占位符仅仅是一个标识,标志这里会有变化,一句话可以概括凡是可以表达变化的就是占位符,具体的变化实现又没有给出,真正体现了做什么和怎么做的分离。

  • 占位符怎么表达要回答这个标识是用什么来表达,变量、接口、配置项…这些都可以表达占位符,变量能被赋值同一类型的数据;接口可以有不同的实现;配置项也可以被赋予不同的值…所以,实现可扩展的思路一下就打开了。

  • 如何实现再往深层次思考,实现一个接口,如何在执行时动态找到实现类?如果把这个问题想清楚,在实际中实现可扩展又会有一套系统性解决方案。整个过程就两点识别和执行,识别的意思就是要找到对应目标,接下来就是执行。

综上,到这里可能已经有自己应对可扩展的方法,上面已经给了从不同角度看可扩展性的示例,接下来就是系统化提出应对可扩展的方法。

结论一扩展的本质就是占位符,凡是可以表达变化的就是占位符。

1.2 应对可扩展的方法

先给出应对可扩展的方法规范、识别、注册、使用,这 4 点都是从上面可推导出来的,下面一一进行详细说明。

  • 规范规范是从占位符推导出来的,既然是标志有变化,一定要遵循一定的规范表达,否则别人是不知道的,如接口,就是很直接地表达这里是有变化的,具体的实现还不知道;变量天然地表达这里是变化的数据。

  • 识别有了规范定义之后,接下来就是识别,之前为什么可扩展一直对我们来讲很虚,那是因为规范和识别都是系统帮我们做的,我们只是知道而没有真正实践。规范是定义,识别是找出有哪些实现了规范。

  • 注册识别出来之后,就要把信息存储起来,可以存储在本地,也可以存储在远程,如果存储在远程就是一个注册的过程,这里的注册就是存储的意思。简单理解就是识别出来之后要集中管理。

  • 使用使用就很简单,找到具体实现并执行逻辑处理。

上面四个单词看起来简单,除了使用是终极目标外,其它三个都是抽象的表达,比如规范如何定义、怎么识别、如何注册?通过上面的表述可以看到具体要怎么实践,这里再下

  • 规范如何去定义凡是可以表达变化的就能用它来定义,常见的有配置项、变量、接口、注解等;

  • 怎么去识别这个要具体去看如何定义规范,如配置项的变化有一个监听变化;注解是要扫描类来识别 annotation;

  • 如何去注册如果系统的交互只是一个,那么存储在本地就行,如果系统的交互是多个,那么要注册到一个注册中心上去。

结论二应对可扩展的方法规范、识别、注册、使用。

1.3 扩展的经典案例

此处使用一个经典案例来说明可扩展性,并从其原理上印证上述方法。

在 Java 中,SPI 对于大部分人来讲并不陌生,最典型的加载数据库驱动就是通过 SPI 来实现的。如果你看了 SPI 的原理,再去看上面写的,会感觉两个思路很相似。

SPI 有它的规范,要到指定目录下加载对应文件;找到文件后进行解析、识别并加载;就是使用。整个流程能印证上面所提到的规范、识别、注册、使用。所以,方法的提出有一个点就是从具体案例中进行抽象,提炼共性的东西,再去推演其它案例看能不能也满足。

二、可扩展性系统实践之路

此处以优惠券业务平台为例讲解可扩展性系统设计与实现,在上一篇文章中已经讲了优惠券系统是一个平台型的业务系统,要做到业务与业务的隔离、业务与平台的隔离。

2.1 识别变化

经过整体分析之后,已经确定大业务流程建券、发券、用券、退券,以及对应的子流程,接下来就是要分析出哪些内容会变化。

比较明显的变化就是领券、用券门槛的变化,因为不同业务线有不同的限制条件,有的要限制不同人群,有的要限制领取次数…已经认别了变化接下来就是要处理这些变化。

结论三找扩展点就是找系统经常变化的地方。

2.2 处理变化的常见手段

2.2.1 野蛮处理

一个最简单的处理,就是在代码中写 if else,它的特点是简单直接上线,不足的点长期下去,系统会变得很难维护、可扩展性较差。

   if(productId = ProductEnum.A){
    // 具体的处理
   }else if(productId = ProductEnum.B){
   // 具体的处理
   }else if(productId = ProductEnum.C){
   // 具体的处理
   }else{
   ......
   }

这种代码放到现在,很多系统还是这么做的,而且是在业务发展初期最喜欢用这种野蛮处理方式,搞上去就能直接上线,快速支持业务。

2.2.2 面向接口设计

对上面野蛮方式的一个常见处理就是面向接口设计,抽象出一个限制条件检查的接口,不同的业务线有对应的实现,通过配置指定业务线下所有的实现,将这些实现放到一个映射中,在程序执行过程中,通过业务线就可以执行所有的接口实现类并依次执行。

  List ruleList = RuleFacotry.getByProductId(prodcutId);

这种方法比第一种明显要好,体现了一定的可扩展性,新加一个规则限制,重新实现接口就行,然后在配置项中加上这个新的实现,代码的改动量也还好。它有一个明显的问题就是每次新加一个实现就要发布上线,有没有方法不发布上线就能满足目的呢?有,就是下面提到的一类可扩展性设计的方法。

2.3 一类可扩展性设计的方法

再来明确一下目标系统具备可扩展性和不发布系统就能实现新增功能。

还是使用上面说的方法规范、认别、注册、使用,下面结合这个具体的案例来说明。

  • 规范这里是用接口来作为规范描述限制条件,包含入参和出参,这里有一个开放平台,实现了一个接口后就可以提交代码。

  • 识别在建优惠券时,会加载业务线有哪些业务规则实现,在领取、使用时可以进行配置选择,此时只是插入一个变量标识使用某个限制条件 (如限人群,这个实现的逻辑可能会变化,通过变量名来标识变化)。

  • 注册系统在执行的过程中,发现有限制条件的变量名,拿这个变量名从开放平台中拉取具体的实现存储在本地 (有一个缓存时间,具体的过期时间依业务考虑,我们取的是 30 分钟)。

  • 执行拿到具体的实现后,依次执行。

再整理下流程步骤,让大家更进一步掌握该设计方法

  • 在开放平台提交限制条件接口的实现代码,有限制人群的实现、限制领取券次数…

  • 在开放平台提交之后,会入库存储,数据库里会存储一个业务线对应的多个限制实现。

  • 创建优惠券时,会加载业务下的限制规则,通过配置选择具体要使用到的限制规则 (相同业务线下的不同优惠券可以有不同的规则限制),配置选择后,会在规范字段中存储规则实现的 id(规则实现可能会变化,会有多次提交),所以这里存储的是 id,在执行的时候可以拿到这个 id。

  • 在领券、用券时,会检查规则限制有哪些,通过 id 列表从远程开放平台拉取具体实现,把 java 代码拉下来之后就可以编译,并存储到本地或者集群缓存中。

  • 就是执行具体的实现逻辑。

结合这张图看就会清晰很多,整体的业务平台架构比较清晰,分为开放平台、配置平台、业务平台和数据平台,一个新业务方接进来很简单,简单配置下就可以使用。

三、小结

本篇文章主要讲可扩展性系统的设计与实现,从可扩展的本质讲起,可扩展的本质就是占位符,凡是可表达变化的都可以称之为占位符,常见的有变量、接口、配置项、注解等,然后提出应对可扩展性的方法规范、识别、注册、使用四个步骤,虽然只有 8 个字,但它包含了一套系统的处理方案,不再是单一的面向接口编程,结合具体的案例进行说明如何设计可扩展性系统。

 

 

from https://.infoq./article/GDTr9RmIyh0hR59ZTug

https://.infoq./article/Uk2eGlWfHNaYjRc8XLy

https://.infoq./article/12MJZzx-0dm9j9VYSam

Copyright © 2016-2025 www.caominkang.com 曹敏电脑维修网 版权所有 Power by