关于有界上下文和微服务的关系以及它们的划分粒度 - Alberto Brandolini


如果您这些年来一直在企业软件体系结构的任何地方工作,您很有可能会遇到诸如“什么是微服务的正确粒度?”之类的问题。或“微服务和有界上下文是否相同?”
在接下来的几段中,我将尽力澄清。

定义
我想澄清的第一个问题是,两个概念都有一个模糊的定义。定义这些概念本身已经很困难,因此将两者结合起来很容易使对话变得含糊不清。
有界上下文是围绕语言构建的。
领域驱动设计的发明者埃里克·埃文斯(Eric Evans)可能需要花费数天的时间寻找完美的词语来传达特定的含义,因此当他选择一个词时……这个词只是可能代表他表达含义。因此,让我们看看Context的原始定义,然后再看看有界上下文Bounded Context(原始资源在这里):

上下文:用来确定其含义的单词或陈述的一种设置

这基本上是一个语言术语。关于世界各地的“ 咖啡 ”一词的不同含义,有无数的故事和笑话,但这就是任何语言的本质。术语如果在其原始范围之外被使用,最初听起来像很奇怪的隐喻,逐渐这也成为对话语言的一部分,依此类推。

语言不是固定的,而是不断发展的。
语言不是固定的,上下文对于实现精度是必不可少的。

但是语言只能在一定程度上帮助我们:编写软件时,我们需要精度。当开发涉及多个上下文的软件时,使某些对话听起来像是在开玩笑的同样模棱两可的情况,将成为错误的危险来源。

那么什么是边界上下文?
在软件世界中,我们需要承担为这种语言一致性设置边界的责任。这就是“ 有界上下文”概念出现的地方。
有界上下文:特定模型的有限适用性。有界上下文使团队成员可以有一个清晰的、共享地理解,这就是那些独立开发的内容必须保持一致性。
这里的定义更接近软件开发领域。有一些隐含的假设,让我们尝试使其明确。

  • 我们正在谈论多种专业模型:不平常的软件将需要不同的模型和不同的样式进行协作。每个问题都会有一个最适合 该特定问题的模型。
  • 团队和有界上下文之间存在紧密的联系:具有明确目标的团队很有可能围绕其特定的问题空间发展出精确的行话。
  • 一刀切的所有标准体系结构没有用。就像在说“我们必须赢得一级方程式赛车冠军”,同时说“所有员工,包括司机,应获得相同的报酬”。(banq注:这些都是大话套话、正确废话,无法付诸实现)

实际上,有界上下文使用这种语言作为煤矿中的金丝雀(banq注:用金丝雀测试煤矿中是否有毒气,它们比较敏感,这也是测试领域的一个专业词语:金丝雀测试):语言对于来自不同来源(团队成员,利益相关者,团队分布,基础技术,时间等)的变化非常敏感。语言中会出现不一致之处,因此我们会留意。
保留边界成为一项有趣的设计活动,因为它意味着通过实现适配器或反腐败层来推动边界处的转换,以使内部模型尽可能简单,或者更好地专注于该特定模型的唯一相关问题。
(banq注:边界敏感性和文化思维方式有关,如果文化中注重个人隐私边界,会培养成对事物和人的边界划分敏感性,如果没有这种文化,注重邻里和谐打成一片,对培养边界敏感性可能不利)

那么什么是微服务?
当要确切地了解微服务是什么时,由于没有单一的中央定义要引用,因此情况甚至更加严峻。但是,Martin Fowler’s Bliki 仍然可以作为权威信息来源。
该术语严格来说是架构性的,但有趣的是,其含义正在整个社会技术体系中产生。

  • 通过服务进行组件化 →这是最明显的部分。它也是与SOA最相似的一种。作为独立部署是一个重要特征。
  • 围绕业务能力进行组织 →跨职能团队为特定的业务目的服务。
  • 产品而非项目 →团队负责整个生命周期,包括生产和维护。
  • 智能端点和哑管道 →将逻辑置于通信通道中最终会使供应商受益(具有可怕的锁定方案),其想法不是要重蹈SOA中ESB供应商所发生的错误。
  • 分散的治理 →本地选择更了解本地问题:因此本地实施应该有更多的自由。(听起来很像我们刚才所说的
  • 分散数据管理 →微服务应拥有自己的持久性。毫不奇怪,Fowler的文章直接提到了有界上下文的概念。
  • 基础架构自动化 →持续交付是必须的。为了提高质量,加快反馈循环等。
  • 故障设计 →应用程序需要容忍服务故障,因此微服务方法的一部分涉及确保故障不会影响用户体验。到目前为止,Netflix是最著名的案例。并引发了有趣的想法,例如四面军和混沌猴子。
  • 进化设计 →并行独立的进化也带来了较小的,可能是不协调的发行版的想法。组件是可独立更换的,并且使用寿命可能不同。

在这里,我试图将两个概念的关键特征重叠起来。

特征有界上下文微服务兼容性

这两个概念一样好像感觉不同但高度兼容。

寻找完美的尺寸
它们不是同一件事:

  • 显然,您可以在不同的体系结构中使用有界上下文:它们比微服务早了大约十年。
  • 只要满足安全建议,您就可以在同一个部署单元内拥有多个有界上下文(例如具有干净内部分隔的整体)。
  • 有界上下文围绕内置目的的模式,微服务围绕部署边界。在某些情况下,驱动力可能相似,但并不相同。

在年轻的初创公司中,开发速度非常重要,因为我们要从头开始构建许多组件,但是物理隔离不同的组件会减慢一切,并且在快速增长的环境中,边界可能会模糊一段时间。常见的策略可能是在整体内部进行逻辑隔离,并仅在达到给定数字时才开始发展体系结构。
在中型公司中,不同的团队已经可以与定义明确的部门合作。目的驱动的边界可能与部署单元以及业务功能重叠。
在某些情况下,可以通过具有多个独立模块的松散耦合组件来实现价值交付。在这种由Netflix闻名的场景中,组件比有界上下文小得多,并且通过诸如Chaos Engineering(Chaos Monkey和Simian Army是著名的例子)之类的激进方法来保持整体行为的完整性,以增强整个系统。

可能的经验法则
我喜欢渐进式架构的想法,而不是预先进行大型设计。(banq注:敏捷?)
有界上下文应围绕目标和语言边界出现。战略愿景的事件风暴是突出并收集这些边界的一种非常有效的方法。
微服务通常会在团队规模和变更频率附近找到独立部署单元的最佳规模。最终部署在一起的拆分组件往往会因协调成本而适得其反,因此自主团队倾向于找到自己的完美平衡。

错误的代价
错误大小的动态是不同的:太细粒度的有界上下文很容易混合,而分离这些已经混合的BC有界上下文则要贵得多。
微服务暴露出相反的风险结构:过于细粒度的服务会增加保持整体结构受控的成本,而将服务拆分成更明确的结构(可能保留前端API)则可以在分析实际服务后按需完成压力。
这种相反作用力的结合通常要求:逻辑上保持边界整洁,在有价值的时候进行物理隔离。

反模式
数据驱动的拆分(无需进行对业务行为的检查和重新设计即可将数据库表的应用直接转换为微服务)也产生了惊人的反作用:新系统与其整体祖先耦合在一起,但速度可能较慢,并且重构成本飞涨。

超越技术
大多数从业者都担心完美的尺寸和技术堆栈。但是真正有趣的属性是在社会技术堆栈的社会部分。
有界上下文为这种实验提供了隔离的空间。隔离是提供安全的基础。如果您的模型与太多的参与者共享,人们将无法进行实验,因为会破坏他人的代码。
良好的有界上下文提供了安全的空间和良好的责任循环。
我们是对此类代码负责的唯一人员。如果这里有错误,我们不能怪任何人。但是我们可以确保代码中完全没有错误。
这种不依赖其他团队或其他技术的小技巧,与考虑周全的微服务似乎朝着同一方向发展,在反馈循环中增加了一些加速,因此领域学习和业务学习也可以通过生产影响快速得到验证。
对我而言,真正使我震惊的是,有界上下文和微服务与丹尼尔·平克(Daniel Pink)《驱动器》的动机原则是融合一致的:自治,精通和目标。

  • 在计划,技术和思维模型方面,尽可能与其他团队保持独立。独立性越高,指责游戏和指责的可能性就越小。
  • 致力于提供高质量的软件并承受不良质量的后果,对于在真正重要的地方提高软件质量是一个很好的环境。
  • 与给定业务能力的直接链接将简化与业务代表的互动,带来更短的反馈循环,更多的学习机会,并最终开启更具实验性和可能的​​创造性对话的可能性。

换句话说:我们一直在技术和工程方面,因为这是我们擅长的,我们可能会忘记我们只是在为软件专业人员建立一个更健康的工作场所。