美文网首页微服务领域驱动设计
脚踏实地系列之领域驱动设计--从微服务谈起

脚踏实地系列之领域驱动设计--从微服务谈起

作者: 志铉 | 来源:发表于2020-01-21 15:11 被阅读0次

    随着14年左右开始,业界开始流行微服务架构,开始是基于Dubbo的微服务,后面慢慢的Spring 开源组织开始发力,SpringBoot 和SpringCloud 相继出来,越来越流行,特别是18年开始,似乎SpringCloud 已经成为项目开发的标配,有一种感觉如果你没搞过SpringCloud,都不好意思和人打招呼。

    本文不是探讨SpringCloud,而是探讨基于微服务的DDD实施,在以前单应用流行于天下时,一个系统一个应用,基本上也没有什么服务的划分,更谈谈不上分库(不考虑性能因素)。所以那个年代,DDD 很多逻辑和概念都无法落地(DDD的方法论应该是Evans于2004年提出),所以让很多人认为很专家,很概念,很不落地。但随着微服务流行,慢慢的大家会意识到一个问题:就是对于一个复杂的系统,需要实施微服务架构时,如何划分服务?

    比如笔者比较熟悉的领域,支付清算行业,一般我们会规划出这样几个微服务:收银台,交易中心,账户,用户,商户,对账,清分,结算等等这些微服务。当然这是笔者沉积了十几年的经验和同行交流学习得出来的经验的划分方法,但这个总感觉是从结果推过程,但当我们面对一个全新的领域时或则经验不足时,如何划分了,这就有这非常花样百出的分法,最终也因为经验的不足,而导致我们的系统微服务也是千奇百怪,我见过有在商户服务里面做记账的,也有在用户服务中,涉及到电商交易的。实际上按照本人的理解,一个相对规范的微服务应该是下面这个样子:

    而因为设计的不合理,划分的拍脑袋,导致出现实际的样子是这样的:

    上面这种微服务在我看来是一种伪微服务,为了微服务而诞生的微服务架构。为什么,因为这里面他很多的微服务都是共用的一个数据库,只是简单的做了一个服务层面的分布式,数据层面依然是逻辑共用的。这样等于只是代码分别放在了不同的地方而已,而且没有任何约束,在这种架构下你还会很容易的发现有其他诸多问题:比如一个数据的更新逻辑,往往分布在多处(原因很多:事务,工程,素质等等),我说的多处是多处服务,那么对于这个数据依赖和耦合度也就和更多的服务相关,这样的实际反而还不如一个单应用来的直接和简单明了。比如订单这个数据,我A服务能改,B服务也同样能改呀,这样在我看来就是一靠自觉,二靠运气的微服务架构,因为我们往往是无法通过这种架构对代码进行合理的维护,甚至性能的提升。

    所以市面上很多公司的所谓的微服务架构其实只是技术上的分布式,而仅仅是为了满足个别技术人员的技术提升的私心,这样的架构设计,也许只有当事人才看得懂,业务和产品无法理解,为了微服务而微服务/具体为了业务,一个产品看得懂,业务瞧得明白,代码逻辑清晰的微服务架构系统其实是比较稀缺的。

    那么DDD 在我看来就是可以解决这个问题(通过建立领域模型再推导出微服务),这也是伴随着微服务的流行,DDD为什么又死灰复燃了(贬义褒用)的根本原因。

    在DDD的实施环节中,对于一个系统,开始并不是划分什么微服务,而是先组织一个活动:事件风暴

    事件风暴在我看来:第一需要组织相关的参与者,最后能邀请到该需求提出者,业务人员,产品设计人员,以及开发代表(应用架构师),测试代表等等。

    然后开始事件风暴:首先是用例收集和分析,再初步的进行领域划分,首先我要提到整个事件风暴虽然有几个步骤,但不是瀑布似的过程,而是迭代的反复进行,不停的设计和修正,尽可能全面不遗漏地分解业务领域。

    用例分析:就是通过一个个需求用例提出用户使用场景和领域划分(用户不光指人类)

    下图是笔者曾经做出的用例分析图一部分(补充:这个只是一部分图,而且是事后在整理在一起的,在分析时,是一个思维发散的过程)

         用例分析第一步就找出复杂用例和长用例,即调用关系复杂,业务链路较长的用例,针对这类型的用例,我们一般认为,这样的用例可以通过:事件传递等方式,将其拆分成小用例。比如用户购买东西支付成功,这个在需求提出的最开始就是一个动作,但伴随业务的流转,它需要经历支付处理过程,订单处理过程,以及商品库存处理过程,以及后续发货等等过程。但我们经过仔细的业务分析,会发现,这个用例完全是可以拆成支付用例,订单状态处理用例。商品处理用例,以及 发货用例等等。那么这些用例间如何进行串联调用了,完全可以通过相应的用例执行结果通知的方式,将用例进行相应的串接。

          通过上面的用例收集和分析过程,我们会发现一些用例在业务的上下文中,基本是可以划为一类:比如电商的 订单处理,物流,支付系统的:对账,结算,支付等等,其实这个就已经初步出现了领域的划分了(注意这还只是初步),然后我们可以在这些领域中,我们可以找寻其中的核心域和支撑域,以及通用域。发现整个系统的核心域,但核心域的划分没有绝对的公式,因为商业模式的不同会导致核心域划分结果的不同。有的公司核心域可能在客户服务,有的可能在产品质量,有的可能在物流。在公司领域细分、建立领域模型和系统建设时,我们就要结合公司战略重点和商业模式,找到核心域了,且应该重点关注核心域。

         虽然没有公式,但如何找到核心域,依照我的经验提出一个问题:这个系统是通过什么东西提供了核心业务服务是什么?注意这个不是技术问题,而是一个业务问题。比如笔者曾经参与过两套支付系统的建设:现今回想起来一套核心域是订单,另一套则是账户。因为这两套系统在不同的商业模型中回答上面的问题是截然不同的。

    找到了核心域,那么自然就可以基于核心域找到其他的如支撑域和通用域等等。支撑域是辅助核心域的(它不通用),通用域是贯穿到整个流程中的一些共用环节。

    但当我们一旦明确了核心域,我们应该将核心域的建设排在首位,最好是有绝对的掌控能力和自主研发能力,如果资源实在有限的话,可以在支撑域或者通用域上想想办法,暂时采用外购的方式也未尝不可。所以当我们需要外包时,我们应该尽可能的外包非核心域的东西,尽可能的选择其他部分。(当然如何控制外包的质量,后面再谈)

    回到我上面的这个示例:我这个支付系统有订单,但由于这个系统后面不光只是支付收单,还涉及到理财,钱包,以及海外货币汇兑(海外牌照)等等业务,所以这个系统的核心域自然是账户体系。 但之前为另一个支付系统为什么核心域是订单了,因为之前的一个系统就是简单的收集支付订单,核对流水,最后把整个订单金额去向进行留存归档即可,所以核心域是不一样的。

    相关文章

      网友评论

        本文标题:脚踏实地系列之领域驱动设计--从微服务谈起

        本文链接:https://www.haomeiwen.com/subject/pasezctx.html