InfoQ如何基于 DDD 构建微服务?


InfoQ如何基于 DDD 构建微服务?
本文插图
作者 | Chandra
译者 | 刘雅梦
策划 | 田晓旭
本文将讨论微服务与 DDD 涉及到的概念、策划和设计方法 , 并且尝试将一个单体应用拆分成多个基于 DDD 的微服务 。
微服务的定义
微服务中的“微”虽然表示服务的规模 , 但它并不是使应用程序成为微服务的唯一标准 。 当团队转向基于微服务的架构时 , 他们的目标是提高敏捷性 , 即自主且频繁地部署功能 。
因此 , 很难给微服务架构风格下一个简单的定义 。 我喜欢 Adrian Cockcroft 关于微服务的简短定义:“面向服务的架构由具有界限上下文、松散耦合的元素组成 。 ”
尽管这定义了一种高级的设计启发式方法 , 但微服务架构具有的特性 , 使其有别于以往的面向服务架构 。 根据以往的文章 , 我们总结了微服务架构应具备的一些特征:
服务以业务上下文为中心定义了良好的边界 , 而不是以任意的技术抽象为中心;
隐藏实现细节 , 并通过意图接口暴露功能;
服务不会共享超出其边界的内部结构 , 例如不共享数据库;
服务具有故障快速恢复能力;
团队职能独立 , 能够自主发布变更;
团队拥护自动化文化 , 例如自动化测试、持续集成和持续交付 。
简而言之 , 我们可以将这种架构风格总结如下:
松散耦合的面向服务的架构 , 其中每个服务都封装在定义良好的界限上下文中 , 支持应用程序快速、频繁且可靠的交付 。
领域驱动设计和界限上下文
微服务的强大之处在于清晰地定义了它们的职责并划定了它们之间的边界 。 它的目的是在边界内建立高内聚 , 在边界外建立低耦合 。 也就是说 , 倾向于一起改变的事物应该放在一起 。 正如现实生活中的许多问题一样 , 但这说起来容易做起来难 , 业务在不断发展 , 设想也随之改变 。 因此 , 重构能力是设计系统时考虑的另一项关键问题 。
在我们看来 , 领域驱动设计 (DDD) 是关键 , 它是设计微服务时必不可少的工具 , 无论是对单体应用进行拆分还是从头开始构建一个新项目 。 领域驱动设计因 Eric Evans 的著作而出名 , 它是一组思想、原则和模式 , 可以帮助我们基于业务领域的底层模型设计软件系统 。 开发人员和领域专家一起使用统一的通用语言创建业务模型 。 然后将这些模型绑定到有意义的系统上 , 在这些系统和处理这些服务的团队之间建立协作协议 。 更重要的是 , 它们设计了系统之间的概念轮廓或边界 。
微服务设计从这些概念中汲取了灵感 , 因为所有这些原理都有助于构建可以独立变更和发展的模块化系统 。
在继续深入之前 , 让我们快速浏览一下 DDD 的一些基本术语 。 对领域驱动设计的完整概述不在本文的讨论范围之内 。
领域(Domain):代表组织所做的工作 。 例如零售或电子商务 。
子域(Subdomain):组织或组织内的业务部门 。 一个领域由多个子域组成 。
统一语言(Ubiquitous language):这是用于表达模型的语言 。 在下面的例子中(图 1) , Item 是一个模型 , 它是每个子域的统一语言 。 开发人员、产品经理、领域专家和业务各涉众方都能就使用这种语言达成一致 , 并在他们的工件(代码、产品文档等)中使用该语言 。

InfoQ如何基于 DDD 构建微服务?
本文插图
【InfoQ如何基于 DDD 构建微服务?】
图 1:电子商务领域中的子域和界限上下文
界限上下文(Bounded Contexts):领域驱动设计将界限上下文定义为“一个单词或语句出现时确定其含义的设置” 。 简而言之 , 这意味着模型在边界内是有含义的 。 在上面的例子中(图 1) , “Item”在每个上下文中都有不同的含义 。 在 Catalog 上下文中 , Item 表示可出售的产品 , 而在 Cart 上下文中 , 它表示客户已添加到购物车中的商品选项 。 在 Fulfillment 上下文中 , 它表示将要运送给客户的仓库物料 。 这些模型各不相同 , 每个模型都有不同的含义 , 并且可能包含不同的属性 。 通过将这些模型分离并将其隔离在各自的边界内 , 我们就可以自由地表达这些模型 , 而不会产生歧义 。