架构方法论之浅谈微服务与划分

原文转自我自己的个人公众号:https://mp.weixin.qq.com/s/W5HBc_LlHUds-ApTutu7Zg

         云原生计算基金会CNCF在云原生的定义中提到:“云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式API”。涉及的这些技术中,最为被人熟知的非微服务莫属。作为近些年最流行的技术名词,微服务被无数软件公司和技术平台追捧,几乎所有的B/S架构的软件系统均在向微服务靠拢。一时间,微服务好像成了可以解决当今软件世界中一切问题的灵丹妙药。但事实并非如此。

        IBM大型机之父弗雷德里克•布鲁克斯在软件工程的经典之作《人月神话》中曾不止一次的提到:“没有银弹”。布鲁克斯断定自1986年开始的十年内,没有任何单独的软件工程进展可以使软件生产率有数量级的提高。在当时,被认为有可能是银弹的技术之一便是面向对象编程。现在已经过去了30多年,结果如何呢?曾经的银弹热门候选人——面向对象编程,也暴露出越来越多的问题,如过度封装和“类爆炸”。

        微服务也不是“银弹”。将单体应用化整为零后,要面对各种各样在单体应用中不曾遇到的问题。如服务间可能出现的高度耦合、分布式事务管理;开发过程中的调试困难;部署拓扑的复杂化;以及运维中的服务治理和监控。在实践中,这些问题还不是首先所要面临的。首先面临的是微服务应该如何划分?而这个问题如果解决不好,将会引起上述问题或扩大问题的影响范围和强度。

        大多数的开发团队在进行微服务转型的时候只是单纯的使用了微服务的技术架构,凭感觉对系统进行划分,做到化整为零,做的好一些的团队进一步做到了服务治理。但技术永远要服务于业务,不恰当的拆分会导致业务的混乱,单纯的使用技术架构将使整个系统耦合度变得越来越高,扩展性随之也会越来越差。微服务的那些优点随着业务的变化越来越难以体现,而缺点却持续放大。因此,一味的追求技术只会适得其反。

        对于微服务应该如何划分,目前业界并没有一套统一的标准,我个人认为的原因是微服务的划分和业务活动有着密不可分的关系。不恰当的划分是造成微服务转型失败的重要原因之一。

        下面结合我的实际经验,对划分方法和实践进行初步的探讨。

        在“The Open Group”组织的企业架构标准“TOGAF”中,架构开发方法包含了业务架构、应用架构、数据架构和技术架构,并且以需求管理为中心。上述的四种架构中,业务架构是其它架构工作的前提。微服务架构的开发也不例外,要想恰当的划分微服务的边界,也必须从业务架构着手。

架构方法论之浅谈微服务与划分_第1张图片

        开发业务架构首先是要对业务进行建模。在这一步中,可以使用的方法是业务场景和业务目标。

        业务场景描述了架构能够启用的业务流程和应用;业务和技术环境;执行该场景的人员以及其它计算机组件和适当执行的期望结果。一个良好的业务场景表达了重大的业务需要或问题,能够帮助理解解决方案对整个系统的价值。业务场景使用“SMART”法则衡量其是否良好:具体的,定义业务中需要完成什么;可衡量的,成功的明确衡量标准;可付诸行动的,明确地划分问题,为确定解决方案和计划提供基础;切实可行地,可在物理现实、时间和成本约束的范围内解决。有时限地,对解决方案何时失效有明确地说明。

        创建业务场景的流程如下:

  • 对驱动该场景的问题进行识别;

  • 识别该场景的业务和技术环境;

  • 识别预期的目的(成功解决问题的结果);

  • 识别参与者及其在业务模型中的位置;

  • 识别计算机施动者及其在技术模型中的位置;

  • 识别每个施动者的角色、职责和成功的衡量标准;

  • 检查“适用性”,并在需要时进行细化。

        通过对业务场景的创建,使用适当UML建模语言对每个业务场景进行建模,如:用例模型、活动模型等。

        有了业务模型后,接下来要做的是对业务模型进行领域分析。要做领域分析,需要先理解什么是领域。在《实现领域驱动设计》一书中,对领域进行了这样的定义:“广义上讲,领域即是一个组织所做的事情以及其中所包含的一切。每个组织都有自己的业务范围和做事方式,整个业务范围以及在其中所进行的活动便是领域”。实际操作中,想要创建一个全功能的领域模型时非常困难的,并且在分析时,关注的通常只是这个业务系统的某个方面。因此,在进行领域分析时,一个领域会被分成若干子域,每个子域都包含一个或多个限界上下文。这里所说的限界上下文即可用来作为微服务的边界。在实际操作中,考虑团队和微服务大小因素,可以将多个限界上下文放入一个微服务中。

        下面我们来看限界上下文是如何划分的。

        限界上下文主要是语言层面的上下文边界,它是划分领域的关键。限界上下文内拥有非歧义的领域特定术语。比如在一个大型系统中,“顾客”这个术语可能有多种含义,在浏览产品目录时,“顾客”一词的上下文是先前购买情况、忠诚度、可买产品、折扣和物流方式;而在下单时,“顾客”的上下文包括名字、产品寄送地址、订单总价和一些付款术语。在一个好的限界上下文中,每个术语应该仅表示一种领域概念。《领域驱动设计》一书中提到了“通用语言”的概念,当一个术语被定义后,该术语应该在设计、开发、绘图、交流中广泛被使用,目的是解决沟通中的术语混淆问题,如沟通双方使用了不同限界上下文中相同的术语造成的混乱。因此每个限界上下文内用于描述的术语都应该是统一语言。

        在思考限界上下文时,不应该从共享数据的角度来考虑,而应该从这些上下文能够提供的功能来考虑。要做到这点并不容易,因为为了实现功能,可能需要交换存储信息的模型,所以首先要问自己“这个上下文是做什么用的”,然后再考虑“它需要什么样的数据”。

        接下来是划分子域,子域可以指导我们如何对系统中的领域进行分组和优先级排序。子域分为确定核心域、支撑子域和通用子域:

  • 核心域:是业务成功的主要促成因素。应给与最高优先级,安排最资深的领域专家和最优秀的开发团队;

  • 支撑子域:支撑子域对应着业务的某个重要方面,但不是核心;

  • 通用子域:如果一个子域被用于整个业务系统,那么整个子域便是通用子域。

        根据限界上下文的依赖关系,将同类型的或关系密切的限界上文划分到一个子域中,然后判断该子域是什么类型的子域。

架构方法论之浅谈微服务与划分_第2张图片

        下面谈谈实际中常遇到的两个问题。

        使用限界上下文对领域划分的时候,最常遇到的问题是“过早划分”。当业务模型还不是很清晰的时候,冒然对领域进行划分的代价可能是十分高昂的。大部分情况中,将一个已有的单体系统划分成微服务,要比从头开始构建微服务简单的多。

        另一个划分中常见的问题是“划分过细”。这个问题普遍存在在刚接触微服务不久的团队中,尤其是在面对新领域的时候,过细的划分可能导致限界上下文间的过度依赖,丧失了独立性。在《微服务设计》一书中有这样的指导方针:一开始,识别出一些粗粒度的限界上下文,而这些上下文可能又包含一些嵌套的限界上下文。当考虑微服务的边界时,首先考虑比较大的、粗粒度的那些上下文,然后当发现合适的缝隙后,再进一步划分出那些嵌套的上下文。

        在我们还没有弄清楚业务模型的时候,不要急于使用微服务,条件允许的话也可以先通过单体应用来过度。划分的时候也可以通过使用较为宽泛的限界上下文划分一个粗粒度的边界。随着系统的上线,我们会对业务有进一步的认识,另一方面,往往业务也会倒逼我们对微服务进行进一步的划分,通过这种方式逐步的缩小服务粒度。

        划分好微服务边界后,就进入实际的开发阶段。目前看到很多开发团队即便服务划分没有问题,也会在实现过程中出问题的情况。这里所说的问题通常是研发流程和团队协作越来越混乱。

        说一个我的亲身经历。我之前所在的一个团队中,所有的服务都由同样的一批人进行维护。一段时间后,大家开始抱怨工作效率低下和开发电脑资源不足。原因是每次开发的时候都需要将所有的依赖服务在本机启动,这消耗了大量的启动时间和本机资源。同时,调试的时候需要切换不同的运行时环境。这种方式被称作“共享服务所有权模式”,可以看出在这种模式下,每个人都需要对所有服务提供开发和支持。

        想要解决上述问题,首先介绍一下康威定律:任何组织在设计一套系统(广义概念上的系统)时,所交付的设计方案在结构上都与该组织的沟通结构保持一致。从康威定律中不难看出,不同的系统架构需要相应的组织架构来支撑。比如原本采用单体架构,那么组织结构可能是所有研发人员属于同一个研发团队,共享同一个代码仓库和数据库。

        采用微服务架构后,需要对组织结构进行适当调整。将原本一个开发团队划分成多个小组,每个小组负责一定数量的服务。服务只能由拥有它的团队负责更改,这样的好处是只要更改不破坏服务的消费者,拥有该服务的团队就可以随时重新组织代码,并且不用关注其它小组的服务。所有权包含服务的方方面面,从应用程序的需求、构建、部署到运维。这种模式在微服务的世界尤为普遍,并且一个小团队更容易负责一个小服务,随着所有权程度的增加会提高自治和交付速度。另外,一个小团队会也更加容易实施敏捷方法论。这样一来,开发团队的结构也与限界上下文保持一致。团队内对限界上下文内使用统一语言表达的术语的理解也变得会更加容易。

        本文仅是对微服务划分进行初步的探讨。在实际应用中,还会碰到各种各样的问题,大部分问题都会有最佳实践和与之匹配的相关理论。但对于刚接触微服务的团队,或者需要大规模使用微服务架构的团队有较高的门槛。尤其是当微服务需要使用云环境以及云原生中的其它技术时,如容器、服务网格等,除此之外使用微服务架构还需要构建一套完整的运维监控体系。这对于大部分开发团队来说并不容易。

        作为后续文章的引子,最后我们简单谈谈为什么需要微服务架构。我个人的观点是微服务可以和DevOps完美的结合,那么它们的应用能做什么呢?在《DevOps实践指南》中提到:“每个公司都是科技公司,无论他们认为自己处在哪个行业。银行也只是拥有银行执照的IT公司而已”。而随着微服务架构的深入应用,结合前后端分离、API集市等技术和手段,企业可以进化出自己的业务中台,让IT资源可以得到最大化的复用、减少投入的同时应对当今高速变化的市场和需求,进而提升企业竞争力。那么问题来了,我们今天只是简单谈了谈微服务的拆分方法,怎么让企业借助微服务架构来实现自己的业务中台呢?后面我们慢慢说。。。。。。

更多内容请关注我的公众号:

你可能感兴趣的:(架构方法论,java,企业架构)