云原生技术系列:微服务 | DDD(领域驱动设计)| 微服务技术框架

导言: 记得自己最早接触类似‘微服务’的理念和实践是在2013年写一个工业级IM系统,当时向往和学习的对象就是腾讯系。特别是腾讯大讲堂中一期《微信之道-至简》对自己的架构理念影响很深,比如下图(1)中体现的就是微服务的设计思想。我也是仿照此架构,设计了我们的IM系统架构。

云原生技术系列:微服务 | DDD(领域驱动设计)| 微服务技术框架_第1张图片

图(1)

后来,基于这种核心架构和相关实现支撑了企业的一些用户级和设备级服务,并在GitHub上开源一个简化的微服务框架项目,这算是自己对微服务最初也是较浅的理解和实用期。

再后来,在经历子业务众多、逻辑复杂、且多产品线的互联网/物联网平台级产品的长期迭代中,对微服务有了更多的使用和实践,对微服务的拆分、微服务的治理也有了更多的理解和实践。近两年在数字化和云原生的实践中微服务理念已然成为“基础中的基础”,我们对微服务相关开源生态的拥抱也热烈了起来。
 
再再后来,就是今天的这篇文章,本是面向团队内部的微服务培训指南,也综合了很多其他优秀的三方内容,独乐乐不如众乐乐,分享给大家参考学习。包含三部分:

  • 讲解微服务核心理念的“微服务概述”;
  • 微服务的拆分和落地方法论:DDD(领域驱动设计);
  • 开源微服务治理框架的选择;

一、微服务概述

1. 服务架构的演进

云原生技术系列:微服务 | DDD(领域驱动设计)| 微服务技术框架_第2张图片

图 服务架构的演进

2. 微服务

微服务是一种分布式软件架构。使用微服务架构可以将一个大型应用程序按照业务或功能模块拆分成多个独立自治的微服务,每个微服务仅实现一种业务或功能,具有明确的边界。为了让各个微服务之间协同工作,它们之间需要通过互相调用或REST等形式的标准接口进行通信和数据交换,是一种松耦合的交互形式。

2.1微服务的优点

  • 单一职责:微服务架构中的每一个服务,都应是符合高内聚、低耦合和单一职责原则的业务逻辑单元。不同的微服务通过互相调用REST等形式的标准接口,进行灵活地通信和组合,从而构建出大的应用系统。
  • 简化复杂应用:微服务的单一职责原则要求一个微服务只负责一项明确的业务,相对于构建一个可以完成所有任务的大型应用程序,理解和实现只提供一个功能的小型应用程序要容易得多。每个微服务单独开发,可以加快开发速度,使服务更容易适应变化和新需求的出现。
  • 独立自治:每个微服务都应该是一个独立的组件,它可以被独立部署、测试、升级和发布,应用程序中的某个或某几个微服务被替换时,其他的微服务都不应该被影响。基于分布式计算、可弹性扩展和组件自治的微服务,与云原生技术相辅相成,为应用程序的设计、开发和部署提供了极大便利。
  • 简化应用部署:在单体的大型应用程序中,即使只修改某个模块的一行代码,也需要对整个系统进行重新构建、部署、测试和交付。而在微服务架构中,则可以单独对指定的服务进行构建、部署、测试和交付。
  • 可灵活组合:在微服务架构中,可以根据不同的目的组合不同粒度的服务为客户提供应用功能,降低应用开发成本,提升开发效率。
  • 可扩展性:根据应用程序中不同的微服务负载情况,为负载高的微服务横向扩展多个副本。
  • 高可靠性、高容错性:微服务独立部署和自治,当某个微服务出现故障时,其他微服务不受影响。
  • 技术异构性:通常在一个大型应用程序中,不同的模块具有不同的功能特点,可能需要不同的团队使用不同的技术栈进行开发。我们可以使用任意新技术对某个微服务进行技术架构升级,只要对外提供的接口保持不变,其他微服务就不会受到影响。
  • 与组织结构相匹配:微服务架构可以很好地将架构与组织结构相匹配,避免出现过大的代码库,从而获得理想的团队大小及生产力。

2.2 对于微服务的建议

  • 考虑首先先构建单块系统,当稳定后再进行拆分

你越不了解一个领域,为服务找到合适的限界上下文就越难。服务的界限划分错误,可能导致不得不频繁地更改服务间的协作,而这种更改成本很高。所以,如果你不了解一个单块系统领域的话,在划分服务之前,第一件事是花一些时间了解系统是做什么的,然后尝试识别出清晰的模块边界。另外,对已有的东西进行分类,要比对不存在的东西进行分类要容易得多。

  • 演进式架构理念

微服务架构会给你带来更多的选择,也需要你做更多的决策。相比简单的单块系统,在微服务的世界中,做决策是一个更为常见的活动。你一定会在一些决策上出错,所以尽量缩小每个决策的影响范围。即使错了,也只会影响系统的一小部分。学会拥抱演进式架构的概念,在这种概念下,系统会在你学到一些新东西之后扩展和变化。不要去想大爆炸式的重写,取而代之的是随着时间的推移,逐步对系统进行一系列更改,这样做可以保持系统的灵活性。

  • 微服务不是银弹

微服务架构在提升开发效率、提升系统扩展能力的同时,也带来了诸多复杂性,比如:运维上的开销、跨进程通信联调的问题、分布式系统的学习成本、排查问题的难度,以及测试回归上的诸多问题。

二、DDD(领域驱动设计)概述

1. 微服务设计为什么要选择 DDD

  • DDD 的核心思想是从业务视角出发,根据限界上下文边界划分业务的领域边界,定义领域模型,确定业务边界。在微服务落地时,建立业务领域模型与微服务代码模型的映射关系,从而保证业务架构与微服务系统架构的—致性。
  • DDD 是一种处理高度复杂领域的设计思想,它试图分离技术实现的复杂性,并围绕业务概念构建领域模型来控制业务的复杂性,以解决软件难以理解,难以演进的问题。
  • DDD 不是架构,它是—种架构设计方法论,它通过业务边界划分将复杂业务领域简单化,帮我们划分出清晰的业务领域和应用边界,从而可以很容易地实现微服务的架构演进。DDD的出现使得原来微服务拆分和设计过程中的问题不再是难题。

2. 如何完成领域建模和微服务的拆分与设计

DDD 包括战略设计战术设计两部分,它们分别从不同的视角出发,完成领域建模和微服务的拆分和设计。

  • 战略设计是从业务视角出发,划分业务的领域边界,建立基于通用语言和业务上下文语义边界的限界上下文,构建领域模型。而限界上下文就可以作为微服务拆分和设计的边界。
  • 战术设计则是从技术视角出发,侧重于对领域模型的技术实现,按照领域模型完成微服务的开发和落地。在战术设计中会有聚合、聚合根、实体、值对象、领域服务、领域事件、应用服务和仓储等领域对象,这些领域对象会以代码的形式映射到微服务中完成设计和系统落地。
    云原生技术系列:微服务 | DDD(领域驱动设计)| 微服务技术框架_第3张图片

    图 DDD 战略设计和战术设计

云原生技术系列:微服务 | DDD(领域驱动设计)| 微服务技术框架_第4张图片

图 基于 DDD 的业务示例

:对于核心子域、通用子域、支撑子域的划分并没有严格的约束,完全根据自身的业务及内部组织语言划分即可。

DDD 战略设计中的领域建模是一个从发散到收敛的过程,通常采用事件风暴工作坊方法。

  • 首先,针对业务领域,通过用例分析、场景分析和用户旅程分析等方法,尽可能全面地、不遗漏地梳理业务领域,发现这些业务领域中的命令、领域事件、领域对象以及它们的业务行为,并梳理这些领域对象之间的关系,这是—个发散的过程。
  • 然后,我们将事件风暴过程中提取的实体、值对象利聚合根等领域对象,从不同的维度进行聚类,形成如聚合和限界上下文等边界,并在限界上下文边界内建立领域模型,这是一个收敛的过程,收敛输出的结果就是领域模型。

3. 微服务的服务封装和调用组合方式

3.1 微服务的服务封装

按照分层架构设计出来的微服务,其内部主要有 facade 接口服务、应用服务、领域服务和基础服务。

  • facade 接口服务:位于用户接口层,包括接口和实现两部分。用于处理用户发送的 RESTful 请求和解析用户输入的配置文件等,并将数据传递给应用层。完成应用服务封装,将 DO 组装成 DTO ,并将数据传递给前端应用。
  • 应用服务层:位于应用层。用来表述应用和用户行为,负责微服务内服务的组合、编排和转发,负责处理业务用例的执行顺序和结果拼装,对外提供粗粒度的服务。
  • 领域服务:位于领域层。领域服务封装核心的业务逻辑,实现需要多个实体协作的核心领域逻辑。它对多个实体或实体方法的业务逻辑进行组合或编排。或者在严格分层架构中对实体的方法进行封装,以领域服务的方式供应用层调用。
  • 基础服务:位于基础层。提供基础资源服务(比如数据库、缓存等),实现各层的解耦,降低外部资源变化对业务应用逻辑的影响。基础服务主要为仓储服务,通过依赖倒置原则提供基础资源服务。领域服务和应用服务都可以调用仓储接口服务,通过仓储实现服务实现数据持久化。

3.2 服务的调用

微服务的服务调用包括三类主要应用场景: 微服务内跨层服务调用,微服务之间调用和领域事件驱动
云原生技术系列:微服务 | DDD(领域驱动设计)| 微服务技术框架_第5张图片

图 微服务的服务封装和服务的调用

4. 总结

DDD 作为—种通用的设计方法,它主要关注从业务领域视角划分领域边界,构建通用语言进行高效沟通,通过业务抽象,建立领域模型,维持业务和代码的逻辑—致性。而微服务作为领域模型的系统落地,它主要关注从领域模型到微服务的代码映射和落地,运行时的进程间通信、容错和故障隔离,实现去中心化的数据管理和服务治理,关注微服务的独立开发、测试、构建和部署。

  • DDD 是一套完整而系统的设计方法,它可以帮你建立一套从战略设计到战术设计的标准设计过程,让你的中台和微服务设计思路更加清晰,设计过程更加规范。
  • DDD 可以处理高复杂度业务领域的软件开发,通过分治策略降低业务和系统建设的复杂度,建立稳定的领域模型。
  • DDD 在领域建模的过程中,强调项目团队与领域专家的合作,在团队内部可以建立良好的沟通氛围,建立团队通用语言。
  • DDD 方法体系中有很多设计思想、原则与模式,深刻理解后可以帮你提高微服务架构的设计能力。
  • DDD 不仅适用于微服务拆分和设计,同样也适用于单体应用。

三、微服务技术框架

1. 微服务框架(生态)的选择——Dubbo、Spring Cloud、K8s + Service Mesh的对比

以下总结大部分摘写自 CSDN用户:chentian114 的文章《技术栈选型之微服务公共关注点及Dubbo、Spring Cloud和K8s横向比对》

我们团队亲自实践的是从Dubbo转向K8s+ServiceMesh(Istio)的技术生态。

1.1 技术实践对比

        Dubbo SpringCloud K8s + ServiceMesh
服务发现和LB ZK/Nacos + client Eureka + Ribbon K8s service
API网关 N/A Zuul/Spring Cloud Gateway Ingress Gateway
配置管理 Diamond/Nacos Spring Cloud Config ConfigMaps/Secrets
熔断限流 Sentinel Hystrix HealthCheck/Probe/ServiceMesh
日志监控 ELK ELK EFK
Metrics监控 Dubbo Admin/Monitor Actuator/MicroMeter+Promethus Heapster+Promethus
调用链监控 N/A Spring Cloud Sleuth/Zipkin Jaeger/Zipkin
应用打包 Jar/War Uber Jar/War Docker Image/Helm
服务语言框架 Dubbo RPC + Java Spring(Boot)REST + Java 框架、语言无关
发布和调度 N/A N/A kube-Scheduler
自动伸缩和自愈 N/A N/A kube-Scheduler/AutoScaler
进程隔离 N/A N/A Docker/Pod
环境管理 N/A N/A Namespace/Authorization
资源配置 N/A N/A CPU/Mem limit,Namespace Quotas
流量治理 N/A N/A ServiceMesh

1.2 生态优劣势对比

    Dubbo SpringCloud K8s + ServiceMesh
优势 阿里背书,成熟稳定,RPC高性能,流量治理方面较细致 Netflix/Pivotal背书,社区活跃,开发体验好,抽象和组件化好 谷歌、CNCF背书,抽象和组件化好,微服务生态统一且完整,支持异构语言,社区活跃
不足 技术较老、更新慢,SDK的耦合度高,仅支持Java技术栈,社区活跃度较低 仅支持Java技术栈,运行耗资源 技术门槛较高,ServiceMesh的sidecar机制有一定的性能损耗

四、参考资料

  • 书籍:《高可用可伸缩微服务架构——基于Dubbo、Spring Cloud和Service Mesh》 2019年出版
  • 杂志:《新程序员003:云原生和全面数字化实践》 2022年出版
  • 书籍: 《中台架构与实现——基于DDD和微服务》 2021年出版

附:文章中的一些资料链接

  • 《微信之道-至简》
  • 《IM系统架构设计之浅见》
  • 《微服务设计》读书笔记
  • 一个简单的微服务框架项目

希望大家关注我最新维护的 GitHub 开源项目,
https://github.com/yaocoder/Architect-CTO-growth
包括技术实践及手册撰写:涵盖DevOps,云原生技术,大数据,人工智能,高并发&高性能&高可用服务等,一起学习成长!如果对你有用,也请星标一下O(∩_∩)O

你可能感兴趣的:(技术体系,架构设计,微服务,云原生,DDD,微服务治理)