微服务与领域驱动设计,架构实践总结

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
简介: 如果软件系统存在持续的迭代周期,那么其中业务、技术、架构的复杂性都会直线拉升,其相应的开发难度也会提高,随之而来的压力会持续在开发和测试之间来回横跳。
怎样的架构才能配得上造到飞起的变化?

一、软件复杂性

1、复杂原因

如果软件系统存在持续的迭代周期,那么其中业务、技术、架构的复杂性都会直线拉升,其相应的开发难度也会提高,可以用一句话总结其根本原因:唯一不变的就是变化;

08-1.png

  • 业务变化:导致复杂性的根本原因,在多端多版本适配的过程中代码快速膨胀;
  • 数据变化:数据随着业务的变化和发展,不断沉淀积累,需要做横向与纵向的管理;
  • 技术升级:技术组件可能因为漏洞,或者更好的解决问题,不间断升级版本;
  • 人员变动:模块的开发人员一旦出现流动,换人接手会给代码带来风格上的差异;
  • 心态起伏:持续应对复杂问题,但平稳的心态很难持续,也是人员流动的一个因素;

应对复杂的变化一直都是软件工程的核心难点问题,如何用较小的架构变化应对较大的业务变化,就是设计中常说的:高内聚、低耦合;还需要补充很重要的一点:单从技术层面是无法持续解决复杂问题的,还需要从管理角度去定义流程标准,规范各种解决方案,是整个部门要持续面对的事项。

2、应对复杂

不管是常说的设计模式、原则、面向对象,还是架构中常用的集群、微服务、领域驱动等,都是在寻求更合理的方案来应对业务的变化;但是没有一劳永逸的解决方法,既要做一定前瞻性的设计去预期业务,同时还要避免过度的设计影响业务进度;这就需要研发团队具备一定的业务高度和技术深度:

08-2.png

在系统落地的过程中,需要对业务深入的分析和理解,不断优化技术层面的解决方案;比如微服务的思想是通过拆分的手段实现业务块之间的低耦合,领域驱动设计则实现各个业务逻辑的高内聚;下面围绕两种方式的实践去详细分析。

二、微服务架构

1、架构设计

系统的架构设计是一件极度复杂的事情,在工作的这几年大致经历过如下几个阶段:单服务、多服务集群、微服务、持续集成;在近2年比较稳定的选型是微服务+自动化集成的模式:

08-3.png

思考其本质的变化逻辑,即为了应对更复杂的业务体系;不管是业务拆分还是模型设计,都是在不断实现高内聚低耦合的原则;降低业务之间的关联影响,分离业务和技术的高度耦合。

2、业务场景

这里先来看一个经典的业务场景:电商交易;基于微服务架构的电商交易场景中,通常至少会涉及如下几个核心服务:交易、账户、订单、商品、仓储、物流;

08-4.png

站在业务角度,进行模块化拆分和管理,结合持续集成的组件,通常可以轻松的应对各种复杂的业务场景,但是不存在真正意义上一劳永逸的手段,业务变化带来的各种问题总会无脑推动开发去寻找更合理的解决方案;

08-5.png

在一次完整的电商交易场景中,实际上真正涉及到的微服务远不止图中的几个,在Trade服务中交织关联多个其他服务,在MVC的分层管理下,初期并不会存在较大风险,但是业务一旦经过多版升级改造之后,并且还存在版本兼容的要求,会给人一种极度混乱和不踏实的感觉;

如果团队成员的综合能力较高,并且版本有充足的时间去设计和优化,这种问题是可以妥善解决的,如果出现时间紧任务重的情况,随之而来的压力会持续在开发和测试之间来回横跳

解决过相关业务场景的研发都知道,重构加持续集成能力,结合严谨的测试,可以应对业务的不断变化;但是在版本兼容的过程中,依然会导致工程中的代码膨胀到飞起,特别是出现中场换人的情况,都会让接手的人员在被埋和离开中,产生一次剧烈的心态挣扎。

3、问题分析

在MVC的架构模式中,工程通常会进行如下的分层管理:控制层、服务层、持久层、存储层;服务层在特定复杂的场景中会做细化拆分,比如第三方对接、常用中间件的二次封装:

08-6.png

对于在复杂业务线上争渡的选手来说,对Mvc分层模式的缺陷是深有体会的,Service层聚焦大量复杂的逻辑,通常核心业务块中总会存在几个代码过千行的实现逻辑,不管用什么思路和模式去拆分封装,都很难解决该层不断扩展带来的膨胀问题。

4、面向过程

在MVC分层中,过程式的代码极其明显,通常以数据库表和关系为基础,映射构建相关实体对象,这些实体对象并没有具体的行为和逻辑,只是作为数据和结构的载体:

08-7.png

从面向对象中类的定义去看:属性和行为;而在MVC模式中,绝大多数实体都只是作为数据的入参出参的结构定义,可以理解为数据容器,在MVC的各层之间不断搬运和加工。

三、领域驱动设计

相比MVC的分层设计,领域驱动设计(Domain-Driven-Design简称DDD)对于复杂业务系统的实现,提出了更加合理的解决方案,DDD模式中涉及大量专业术语和抽象概念,可以参考EricEvans的相关书籍,本文只描述实践中的核心概念。

1、分离模式

DDD模型在分层设计上,划分出核心的四层:接入层、应用层、领域层、基础设施层;注意这里只是单纯站在服务端的常规架构角度去看,很明显分离MVC模式中的服务实现层的逻辑:

08-8.png

其中领域层是关键所在,用来封装复杂的业务,对应用层提供业务管理的核心支撑;整个模型也更具备纵向思维,有效的缓解单层复杂度过高的现象;单从模型设计上看,在工程中基于该分层去管理代码包,也可以使每层的设计更加清晰和独立。

2、设计思想

领域驱动设计并不是简单的分层管理模型,涉及诸多抽象逻辑与专业术语,例如:领域、界限上下文、实体、聚合、值对象等等;

2.1 领域

领域可以理解为业务场景中需要解决的问题合集,是具有范围和边界的约束;领域可以拆分多个子域,通常描述为:核心域、支撑域、通用域:

08-9.png

关于子域的划分也是参考业务属性,可以把核心域理解为最关键的业务场景,并且需要资源倾斜以应对其不断的发展;支撑域可以理解为相对稳定的业务;通用域偏向系统架构层面的公共能力;通过对领域的拆分实现业务分治,这与微服务的拆分思想相符合,两种模式在业务角度是比较统一的;

2.2 界限上下文

DDD中最晦涩难懂的一个抽象概念,特定模型的限界应用,不过可以借用原文的比喻会意一下:细胞之所以能够存在,是因为细胞膜限定了什么在细胞内,什么在细胞外, 并且确定了什么物质可以通过细胞膜:

08-10.png

界限上下文的定义涉及粒度的思想,即每个粒度要具备独立性;如上图仓储业务,可以将服务部署与仓储子域、仓储上下文做成一一对应的关系,或者在仓储子域中分别定义:仓库和货架两个上下文;这里具有极大的灵活性,没有真正意义上的标准可以参考。

2.3 映射关系

做好界限上下文的划分,理清各个上下文之间的关系,明确业务场景中的依赖顺序,这样可以更好的推动开发流程的落地;对于上下文的关系描述也远不止图中的这些,还有共享内核、合作等等:

08-11.png

  • 上下游(U-上游,D下游):描述上下文调用时的关系,服务调用方为D,服务提供方为U;
  • 防腐层(Anticorruption-Layer,简写ACL):上下文交互时封装的一层,提供对动作的校验、适配、转换等;
  • 开放主机服务,发布语言(Open-Host-Service简写OHS,Published-Language简写PL):定义访问协议;

在上下文交互时,防腐层可以维护上下文的隔离和独立,确保调用方不直接依赖服务提供方,从而实现不同上下文之间的依赖解耦;同时这也会带来大量的对象转换动作;

2.4 建模设计

子域和界线上线文完成对业务的拆分切块,从而进行分治;基于防腐层降低各个界限上下文的耦合程度;聚合思想保证了业务问题的解决方案内聚;严格的分层模型实现服务支撑能力的分散;

08-12.png

  • 防腐层(Anticorruption-Layer):上下文交互时封装的一层;
  • 领域层(Domain-Layer):在分层架构中负责领域逻辑的设计和实现;
  • 领域服务(Domain-Service):行为无法识别归属的实体时,封装到领域服务;
  • 聚合(Aggregate):相关对象的集合,描述核心领域,通常把聚合作为数据修改的单元;
  • 实体(Entity):通过标识来定义的对象,而不是基于属性,比如Uid标识用户实体;
  • 值对象(Value-Object):描述特征或属性但没有标识的对象;
  • 工厂(Factory):封装对象复杂的创建逻辑与类型;
  • 存储库(Repository):把存储、缓存、搜索等资源封装的机制,对应领域模型;

领域模型的核心追求目标:高内聚、低耦合;更加抽象的、复杂的设计思想,也同样意味着落地实现的难度更高,但不可否认领域模型作为复杂业务的解决方案,逻辑上的确更加合理。

3、工程实践

领域模型在代码工程的实践中,可以将不同的子域集成到各自的服务中,也可以在一个服务中,通过多个模块(Module)进行隔离维护,即一个模块对应一个界限上下文;

08-13.png

将业务问题进行分模块分层分包的方式进行隔离,是代码工程中的基本手段,这里只是对组织方式进行描述,在实际的开发中,要根据依赖顺序进行类库拆包管理;

在程序的执行过程中,并不是所有的交互命令都需要经过领域层,实际上大部分业务中的查询命令都是超过增删改命令的,所以在纯读取数据的请求中,应用层可以绕开领域层直接访问基础设施层,减少一层数据处理逻辑。

四、实践总结

最后来讨论一些架构实践的经验,随着技术的不断发展和更新换代,为解决业务问题提供了极大的便利,不管是单服务中各种成熟的组件,又或者分布式中的微服务体系,或者聚焦业务管理的领域模型;每种架构选型都有其适用的场景,不同的选型意味着不一样的实现成本;

实际上在做架构选型时,成熟有经验的主导者,都极其擅长做折中处理,也就是常说的退一步海阔天空;通常需要考虑团队的综合水平与业务需求和产品设计,当然在实际的协作流程中多方都是需要相对让步的,但是对质量的要求以及核心业务的实现逻辑上是不能打折的。

五、参考源码

编程文档:
https://gitee.com/cicadasmile/butte-java-note

应用仓库:
https://gitee.com/cicadasmile/butte-flyer-parent
相关文章
|
23天前
|
弹性计算 API 持续交付
后端服务架构的微服务化转型
本文旨在探讨后端服务从单体架构向微服务架构转型的过程,分析微服务架构的优势和面临的挑战。文章首先介绍单体架构的局限性,然后详细阐述微服务架构的核心概念及其在现代软件开发中的应用。通过对比两种架构,指出微服务化转型的必要性和实施策略。最后,讨论了微服务架构实施过程中可能遇到的问题及解决方案。
|
23天前
|
Java 开发者 微服务
从单体到微服务:如何借助 Spring Cloud 实现架构转型
**Spring Cloud** 是一套基于 Spring 框架的**微服务架构解决方案**,它提供了一系列的工具和组件,帮助开发者快速构建分布式系统,尤其是微服务架构。
142 68
从单体到微服务:如何借助 Spring Cloud 实现架构转型
|
22天前
|
运维 监控 持续交付
微服务架构解析:跨越传统架构的技术革命
微服务架构(Microservices Architecture)是一种软件架构风格,它将一个大型的单体应用拆分为多个小而独立的服务,每个服务都可以独立开发、部署和扩展。
152 36
微服务架构解析:跨越传统架构的技术革命
|
25天前
|
设计模式 负载均衡 监控
探索微服务架构下的API网关设计
在微服务的大潮中,API网关如同一座桥梁,连接着服务的提供者与消费者。本文将深入探讨API网关的核心功能、设计原则及实现策略,旨在为读者揭示如何构建一个高效、可靠的API网关。通过分析API网关在微服务架构中的作用和挑战,我们将了解到,一个优秀的API网关不仅要处理服务路由、负载均衡、认证授权等基础问题,还需考虑如何提升系统的可扩展性、安全性和可维护性。文章最后将提供实用的代码示例,帮助读者更好地理解和应用API网关的设计概念。
56 8
|
24天前
|
运维 监控 Java
后端开发中的微服务架构实践与挑战####
在数字化转型加速的今天,微服务架构凭借其高度的灵活性、可扩展性和可维护性,成为众多企业后端系统构建的首选方案。本文深入探讨了微服务架构的核心概念、实施步骤、关键技术考量以及面临的主要挑战,旨在为开发者提供一份实用的实践指南。通过案例分析,揭示微服务在实际项目中的应用效果,并针对常见问题提出解决策略,帮助读者更好地理解和应对微服务架构带来的复杂性与机遇。 ####
|
24天前
|
算法 NoSQL Java
微服务架构下的接口限流策略与实践#### 一、
本文旨在探讨微服务架构下,面对高并发请求时如何有效实施接口限流策略,以保障系统稳定性和服务质量。不同于传统的摘要概述,本文将从实际应用场景出发,深入剖析几种主流的限流算法(如令牌桶、漏桶及固定窗口计数器等),通过对比分析它们的优缺点,并结合具体案例,展示如何在Spring Cloud Gateway中集成自定义限流方案,实现动态限流规则调整,为读者提供一套可落地的实践指南。 #### 二、
48 3
|
23天前
|
消息中间件 运维 安全
后端开发中的微服务架构实践与挑战####
在数字化转型的浪潮中,微服务架构凭借其高度的灵活性和可扩展性,成为众多企业重构后端系统的首选方案。本文将深入探讨微服务的核心概念、设计原则、关键技术选型及在实际项目实施过程中面临的挑战与解决方案,旨在为开发者提供一套实用的微服务架构落地指南。我们将从理论框架出发,逐步深入至技术细节,最终通过案例分析,揭示如何在复杂业务场景下有效应用微服务,提升系统的整体性能与稳定性。 ####
35 1
|
24天前
|
监控 安全 持续交付
构建高效微服务架构:策略与实践####
在数字化转型的浪潮中,微服务架构凭借其高度解耦、灵活扩展和易于维护的特点,成为现代企业应用开发的首选。本文深入探讨了构建高效微服务架构的关键策略与实战经验,从服务拆分的艺术到通信机制的选择,再到容器化部署与持续集成/持续部署(CI/CD)的实践,旨在为开发者提供一套全面的微服务设计与实现指南。通过具体案例分析,揭示如何避免常见陷阱,优化系统性能,确保系统的高可用性与可扩展性,助力企业在复杂多变的市场环境中保持竞争力。 ####
41 2
|
24天前
|
消息中间件 运维 API
后端开发中的微服务架构实践####
本文深入探讨了微服务架构在后端开发中的应用,从其定义、优势到实际案例分析,全面解析了如何有效实施微服务以提升系统的可维护性、扩展性和灵活性。不同于传统摘要的概述性质,本摘要旨在激发读者对微服务架构深度探索的兴趣,通过提出问题而非直接给出答案的方式,引导读者深入
43 1
|
25天前
|
负载均衡 监控 API
后端开发中的微服务架构实践与挑战
本文深入探讨了微服务架构在后端开发中的应用,分析了其优势和面临的挑战,并通过案例分析提出了相应的解决策略。微服务架构以其高度的可扩展性和灵活性,成为现代软件开发的重要趋势。然而,它同时也带来了服务间通信、数据一致性等问题。通过实际案例的剖析,本文旨在为开发者提供有效的微服务实施指导,以优化系统性能和用户体验。