DDD神药:去哪儿结合DDD,实现架构大调优

尼恩说在前面

在40岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格,遇到很多很重要的面试题:

谈谈你的DDD落地经验?

谈谈你对DDD的理解?

如何保证RPC代码不会腐烂,升级能力强?

微服务如何拆分?

微服务爆炸,如何解决?

你们的项目,DDD是怎么落地实操的?

所以,这里尼恩给大家做一下系统化、体系化的梳理,使得大家可以充分展示一下大家雄厚的 “技术肌肉”,让面试官爱到 “不能自已、口水直流”

也一并把这个题目以及参考答案,收入咱们的 《尼恩Java面试宝典PDF》V129版本,供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平。

《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》的PDF,请到文末公号【技术自由圈】获取

除了本文,尼恩输出了一个 《从0到1,带大家精通DDD》系列,帮助大家彻底掌握DDD,链接地址是:

《阿里DDD大佬:从0到1,带大家精通DDD》

《阿里大佬:DDD 落地两大步骤,以及Repository核心模式》

《阿里大佬:DDD 领域层,该如何设计?》

《极兔面试:微服务爆炸,如何解决?Uber 是怎么解决2200个微服务爆炸的?》

《阿里大佬:DDD中Interface层、Application层的设计规范》

《字节面试:请说一下DDD的流程,用电商系统为场景》

《DDD如何落地:去哪儿的DDD架构实操之路》

《DDD落地:从腾讯视频DDD重构之路,看DDD极大价值》

《DDD落地:从美团抽奖平台,看DDD在大厂如何落地?》

《美团面试:微服务如何拆分?原则是什么?》

大家可以先看前面的文章,再来看本篇,效果更佳。

另外,尼恩会结合一个工业级的DDD实操项目,在第34章视频《DDD的学习圣经》中,给大家彻底介绍一下DDD的实操、COLA 框架、DDD的面试题。

DDD现在非常火爆,是有其巨大生产价值,经济价值的, 绝不仅仅是一套概念那么简单。

DDD的绝大价值,具体请参见以下视频:

从腾讯视频DDD重构案例,看看DDD极大价值

文章目录

    • 尼恩说在前面
    • 1、案例简述
    • 2、案例背景及问题分析
      • 背景
      • 问题及表现
        • 问题分析一
        • 问题分析二
    • 3、案例分析与规划
      • 技术架构构想
      • 技术架构调整规划
        • 明确战略调整核心
        • 明确和之前的区别
      • 优势劣势分析
        • 优势(偏向中台方向)
        • 劣势及可能带来的问题
    • 4、案例落地过程
      • 系统架构调整
      • 组织架构调整
      • 技术方案标准制定
      • 请求处理标准化
        • 方案制定
        • 参数透传
    • 5、案例总结
    • 说在最后
    • 尼恩技术圣经系列PDF

1、案例简述

作者:郑吉敏,2019年8月入职去哪儿网,机票目的地事业群技术总监、技术委员会委员、业务架构 SIG 负责人,负责酒店报价中心团队、业务架构组。

2020 年疫情对旅游行业影响特别大,公司层面进行了组织架构的调整,酒店业务也经历了深刻的变革。在新的业务团队着手推进实际需求时,他们遇到了产研效率的新问题,主要表现为产品研发需要与多个技术团队协作,导致整体技术架构与业务发展失去同步。

鉴于之前领域驱动设计(DDD)的成功实践,酒店技术部门在2021年中旬主动发起了一次以DDD为指导思想的技术架构战略调整,包括组织架构和系统架构的优化,并设定了一系列核心技术方案的规范。本次将重点阐述这次战略调整的确认和实施过程。通过对这次战略调整的剖析,我们可以看到康威定律和领域驱动设计思想在其中所起的关键作用。

2、案例背景及问题分析

背景

2020 年初,全球爆发了新冠疫情,对旅游行业影响比较大。2020年5月,公司进行了重大调整,首先组建了机票目的地事业群,将机票和酒店两大事业部从独立运营调整为合并为一个事业群。此外,公司还对服务、用户体验等团队进行了统一管理,使之对事业群负责。同时,公司制定了机票与酒店业务交叉的战略目标,旨在提高用户购买机票后的酒店预订体验。

在面对这些组织架构和业务架构调整的同时,我们开始思考如何调整系统架构以支撑这些变化。带着这个疑问,我们来探讨实际过程中遇到的一些问题。

问题及表现

产品吐槽

  • 几乎每个需求都需要与多个技术团队沟通,合作过程繁琐
  • 很多需求的技术方案经常需要升级,才能达成共识

引申问题

  • 一些看似简单的需求,实际上涉及到的链路较长,总有团队在无需修改逻辑的情况下也要进行透传
  • 在讨论技术方案时,不同团队对于某个逻辑由谁来实现存在分歧,本质上是职责边界不够清晰
问题分析一

先来看一下主流程核心的交互:

DDD神药:去哪儿结合DDD,实现架构大调优_第1张图片

(注:图中 List 代表列表页、Detail 代表详情页、Booking 代表预订页,Order 代表订单页)

通过上图的交互流程,我们可以总结出以下几个问题:

  • 所有核心流程都涉及的团队是报价团队,报价团队是后端团队,比较底层
  • 用户端跨页面交互的统一处理需要在底层的报价团队完成
  • 底层修改,会带动整个链路跟着修改(典型的比如:基础数据新增字段)
  • 报价团队的核心职责是根据用户需求计算酒店房型、价格及优惠细节,而基础数据和相关逻辑不需要过多关注
问题分析二

继续看一下主流程核心团队及核心设计:

DDD神药:去哪儿结合DDD,实现架构大调优_第2张图片

通过上图,我们可以总结出以下几点:

  • 很多团队在自己的领域层上面都有应用层
  • 这些应用层导致了一些任务上下游团队都能完成
  • 而在众多团队都能承担任务的情况下,可能会出现无人愿意承担的情况
  • “万金油”式的架构在业务上升期较为适用,不适合稳定期

3、案例分析与规划

基于 Explicit Architecture(清晰架构)分析

DDD神药:去哪儿结合DDD,实现架构大调优_第3张图片

上图来自国外顶级架构师 herberto graca 的博客(https://herbertograca.com/),融合了 DDD、洋葱架构、整洁架构、CQRS 的”清晰架构“,这个架构有很多优势,比如:

  • 从外向内,越向内越偏核心原则,核心原则相对稳定。核心原则就是常规的领域层,提供核心能力
  • 外层基于核心原则适应不同业务场景,整合内层能力。这一外层主要包括接口层和应用层,主要使用主动适配器模式,重点关注 BFF 及对内层能力的聚合
  • 内层不依赖外层,不受业务变化而变化,关注能力的扩展,完成核心策略实现
  • 边界明显,尤其是领域层与应用层之间
  • CQRS 机制,耦合度低,通过外层整合内层能力,动态适应业务变化,提高扩展性

技术架构构想

结合清晰架构的特点来思考技术架构整体的调整策略

  • 核心思路:整体架构按照DDD分层架构进行,严格区分应用层和领域层

  • 核心动作:将包含核心领域的团队各自的“应用层”交出,统一交给下游网关团队,形成统一的应用层,这些团队的工作将转变为一个个核心领域

DDD神药:去哪儿结合DDD,实现架构大调优_第4张图片

技术架构调整规划

围绕上面的构想,整体架构图期望如下图所示:

DDD神药:去哪儿结合DDD,实现架构大调优_第5张图片

通过上面这个图可以明确几个关键点:

明确战略调整核心
  • 突出核心领域,壮大“大前台”(内部称为主站,此处为方便理解调整为“大前台”)
明确和之前的区别
  • 负责核心领域的团队聚焦可复用能力,专注核心策略和玩法改进
  • 负责应用层的团队关注业务识别与扩展,专注业务模型设计和整合下游能力
  • 业务收敛到一个团队,这个团队了解下游可提供的能力,能从全局角度看待业务开展

优势劣势分析

围绕着上面的调整,分析一下优劣和劣势

优势(偏向中台方向)
  • 减少影响团队:很多需求,产品只需要对接前台一个团队即可,即上文提到的“大前台”团队
  • 减少数据链路:主流程链路变短,设计技术方案、出问题定位及解决都更容易,典型的就是基础数据链路不再经过报价团队给到下游

这两点,在实际中都验证了确实可以起到产研提效作用。

劣势及可能带来的问题
  • 短期内,已有的工作习惯发生变化:数据链路发生变化,需要多个团队配合落地,然后适应新的链路,同时要适应新的架构
  • 可能带来上游团队人员不稳定:这将导致一些杂活完全交给“大前台”,如果一些人长期从事杂活或小需求,可能会出现人员不稳定的问题。此时需要考虑为这些人安排核心任务,改善业务建模等

4、案例落地过程

系统架构调整

  • 应用归属团队调整
  • 已有逻辑归属调整

这里主要完成的是,将做“应用层”的应用及逻辑上交给大前台团队,先保证各自团队负责该负责的事情,让负责核心领域的团队实际主要负责领域的事情,其他交给大前台

组织架构调整

  • 组织架构按需调整:比如多个网关合并成大前台,同时借助一些需求完成一些人员交叉
  • 核心人员归属团队规划:这里主要是 review 一遍核心成员,看看适合领域团队还是大前台,必要时进行相关调整
  • HC 调整,招聘计划跟进:本次会按需为大前台团队增加 hc,同时加紧招聘节奏保证人员尽早就位,这样也可以避免个别成员不稳定对整体的影响程度
  • 成立业务架构组:监督及保证架构调整,同时避免之后的腐化

技术方案标准制定

数据回传标准化

  • SPU 维度:供应链 -> 基础数据(商家、酒店等信息) -> 大前台 -> 端

DDD神药:去哪儿结合DDD,实现架构大调优_第6张图片

  • SKU 维度:供应链 -> 报价 (酒店房型及价格优惠,类比电商里的商品) -> 大前台 -> 端

DDD神药:去哪儿结合DDD,实现架构大调优_第7张图片

依据 SPU、SKU 数据回传标准进行链路优化:对比之前的链路,我们需要对基础数据进行一次全面的改造。首先,我们基于 DDD 思想对基础数据进行领域划分,然后根据领域提供相应的对外 API 服务,直接对接大前台。大前台在接收报价团队的应用层应用(内部名为 mprice)时,将原有服务合并至现有应用层应用,并对接基础数据服务 API。这样,链路从之前的 7 个应用缩短至 4 个应用,同时将一些串行操作并行化,不但链路缩短了,同时主流程响应时间降低了 25%,效果特别好。

请求处理标准化

方案制定

DDD神药:去哪儿结合DDD,实现架构大调优_第8张图片

上图是我们主流程计算用户支付价的几个核心过程。重点解释一下【商促】:基于用户画像打包,满足特定要求(比如特定的用户身份)的营销活动,拿到更低的底价,获得更高的利润。

接下来讨论一个实际问题:临近节日,业务侧希望解除某些商促限制,让所有用户均可享受。此时,技术方案该如何设计?我们给出两种常规方案:

  • 前台修改用户身份,其他团队不感知。该方案存在的问题:用户身份本质上未发生变化,此时查看用户身份会导致其他链路受到影响
  • 报价团队识别场景,做特殊商促匹配。该方案存在的问题:报价团队原本提供正常能力,现在需要提供定制化功能,与原有定位相差较大

这两种常规方案均存在明显问题。那么,问题究竟出在哪里呢?根本原因是标准方案中缺乏对【场景】的应对。

我们结合下图聊一下业务场景中的身份和场景。

DDD神药:去哪儿结合DDD,实现架构大调优_第9张图片

内部做了多次讨论后,最终给出结论:

  • 身份:任意时刻下描述用户(userid)不因此刻本身行为及外部条件影响的自身描述性质或特征的有限个数的标识
  • 场景:谁(who)在何时(when)何地(where)发生了什么事件(what)产生了何种结果 or 情景(how)的标识

举个例子,酒店新客户和机酒用户都是在一段时间内具有一定消费行为(如购买酒店服务、机票等)的用户。通过userid,我们可以直接明确地识别出他们,这属于身份范畴。而“异地面纱”则是一个场景例子,因为对于一个确定的userid,如果他的常住地为北京,而这次要去其他地方,那么“异地”这个条件才能得以满足。需要注意的是,身份特征的数量是有限的,比如门店新客户,对于一个用户来说,他是否是某个门店的新客户通常是明确的。但是,如果我们有近百万家门店,就不适合将其作为身份标识,因为在查询userid时,列出每个门店的信息代价过大,这种更适合拿着 userid + 门店去查询。

在我们的业务场景中,通常都是基于正常定义的身份进行标准计算。如果无法使用身份进行匹配,就需要借助场景来解决问题。

基于对【身份】和【场景】的理解,针对前面的问题,我们给出更合理的方案**:报价提供“强制使用指定商促能力”前台识别场景,组装使用新能力。**这样,报价仍然关注能力提升,前台主要负责业务适应和组装能力,核心是正确使用身份和场景。

DDD神药:去哪儿结合DDD,实现架构大调优_第10张图片

补充说明一下,按照这样架构调整及技术方案执行后,从整体来看整个架构:

  • 领域层能实际暴露出能力,应用层最终暴露出去功能
  • 由于应用层可以根据需求组装各种能力,因此具备很高的扩展性;而对于领域层来说,它专注于能力的复用,因此更具稳定性
  • 应用层通过标准的身份和场景来组装领域层的能力。要么基于标准身份使用常规能力,要么根据场景强制使用特殊能力
  • 功能是为了解决实际场景需求而存在的,变化频繁,因此需要提供众多接口来实现定制功能。而能力则需要尽可能忽略场景,这样才能实现最大程度的复用。为了解决这两者之间的矛盾,我们需要合理地使用身份和场景。
参数透传

在日常开发过程中,我们经常会遇到需要将一个参数透传给上游应用的情况。这种情况下,链路上参与透传的团队和应用往往不需要进行任何业务逻辑处理,却增加了开发工作量,并影响了定义的API。为了解决这个问题,公司内部的业务研发和基础研发部门共同讨论并确认开发了一个新的通用组件:QShareData。各个应用可以根据请求将数据写入QShareData组件,相应的数据id会随trace一起传递。链路上的其他应用可以根据需求通过数据id获取其他应用写入组件的数据,从而减少无意义的透传。当然,这里涉及到一些权限、性能和合理使用等问题,需要结合实际进行相应的限制和要求。

DDD神药:去哪儿结合DDD,实现架构大调优_第11张图片

5、案例总结

DDD神药:去哪儿结合DDD,实现架构大调优_第12张图片

首先,我们来回顾一下著名的康威定律:设计系统的组织,其产生的设计等同于组织之内、 组织之间的沟通结构。康威定律成立说明组织架构与系统之间必须匹配,但未强调合理。

接下来,我们再看一下 DDD 中的康威定律,它的核心观点是系统架构主导组织架构。由于DDD立足于业务领域,回归业务本质,因此其与业务的契合度较高,更易于实现合理性。

有些人可能会疑惑:如何划分团队才能与业务紧密结合?其实,这个问题的本质在于让DDD中的制约因素成为需要改变的目标。为此,我们可以从以下两个方面着手:

  • 以DDD所提炼的业务领域模型为基准,审视并调整组织架构,合理划分团队
  • 依据业务领域结构构建网状组织架构,并在业务发生重大变化时保持组织架构的灵活性,从而使康威定律发挥反向作用

如此一来,我们便能更好地实现团队与业务的匹配,推动组织架构和系统设计的协调发展。在这个过程中,康威定律为我们提供了一种指导思想,帮助我们认识到组织架构与系统设计之间的相互影响关系。同时,通过领域驱动设计,我们能够更加明确业务领域模型,从而调整组织架构,使其与业务发展相适应。

总之,要想实现团队与业务的紧密结合,关键在于以DDD为指导,审视组织架构,合理划分团队,并在业务变化时保持组织架构的灵活性。这样,我们就能让康威定律发挥积极作用,推动组织与系统设计的和谐发展。

说在最后

DDD架构如何落地,是是非常常见的面试题。

以上的内容,如果大家能对答如流,如数家珍,基本上 面试官会被你 震惊到、吸引到。

在面试之前,建议大家系统化的刷一波 5000页《尼恩Java面试宝典PDF》,并且在刷题过程中,如果有啥问题,大家可以来 找 40岁老架构师尼恩交流。

最终,让面试官爱到 “不能自已、口水直流”。offer, 也就来了。

当然,关于DDD,尼恩即将给大家发布一波视频 《第34章:DDD的学习圣经》, 帮助大家彻底穿透DDD。

尼恩技术圣经系列PDF

  • 《NIO圣经:一次穿透NIO、Selector、Epoll底层原理》
  • 《Docker圣经:大白话说Docker底层原理,6W字实现Docker自由》
  • 《K8S学习圣经:大白话说K8S底层原理,14W字实现K8S自由》
  • 《SpringCloud Alibaba 学习圣经,10万字实现SpringCloud 自由》
  • 《大数据HBase学习圣经:一本书实现HBase学习自由》
  • 《大数据Flink学习圣经:一本书实现大数据Flink自由》
  • 《响应式圣经:10W字,实现Spring响应式编程自由》
  • 《Go学习圣经:Go语言实现高并发CRUD业务开发》

……完整版尼恩技术圣经PDF集群,请找尼恩领取

《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》PDF,请到下面公号【技术自由圈】取↓↓↓

你可能感兴趣的:(技术圣经,面试,架构,后端,java,面试,系统架构,微服务,中间件)