你是否还在为微服务应该拆多小而争论不休?到底如何才能设计出收放自如的微服务?怎样才能保证业务领域模型与代码模型的一致性?或许本文能帮你找到答案。
本文是基于DDD的微服务设计和开发实战篇,通过借鉴领域驱动设计思想,指导微服务项目团队进行设计和开发本文包括三部分内容:第一部分讲述领域驱动设计基本知识,包括:分层架构、服务视图、数据视图和领域事件发布和订阅等;第二部分讲述微服务设计方法、过程、模板、代码目录、设计原则等内容;最后部分以一个项目为例讲述基于DDD的微服务设计过程。
一、 目标
本文采用DDD(领域驱动设计)作为微服务设计指导思想,通过事件风暴建立领域模型,合理划分领域逻辑和物理边界,建立领域对象及服务矩阵和服务架构图,定义符合DDD分层架构思想的代码结构模型,保证业务模型与代码模型的一致性。通过上述设计思想、方法和过程,指导团队按照DDD设计思想完成微服务设计和开发。
通过领域模型和DDD的分层思想,屏蔽外部变化对领域逻辑的影响,确保交付的软件产品是边界清晰的微服务,而不是内部边界依然混乱的小单体。在需求和设计变化时,可以轻松的完成微服务的开发、拆分和组合,确保微服务不易受外部变化的影响,并稳定运行。
二、 适用范围
本文适用于按照DDD设计方法进行微服务设计和开发的项目及相关人员。
以下情况不适用:
1、“我们的目标是按期盖出一栋大楼来,不要跟我提什么方法,有这啰嗦的时间,还不如抓紧点时间搬砖,把楼给我快点盖好!”。
2、“我的工作就是让软件运行起来,能工作一切就OK!我不需要那么多约束,什么设计方法、扩展性、业务变化、领域模型、响应能力与我无关。别耽误工期啦!先上线再说!”。
3、“好的软件是自己演进出来的,我们不需要设计!”。
哈哈,开个玩笑啦!其实设计不会花太多时间的!
不耽误大家时间了,言归正传。
三、 DDD分层架构视图
DDD分层架构包括:展现层、应用层、领域层和基础层。
DDD分层架构各层职能如下:
1、 展现层
展现层负责向用户显示信息和解释用户指令。
2、 应用层
应用层是很薄的一层,主要面向用户用例操作,协调和指挥领域对象来完成业务逻辑。应用层也是与其他系统的应用层进行交互的必要渠道。应用层服务尽量简单,它不包含业务规则或知识,只为下一层的领域对象协调任务,使它们互相协作。应用层还可进行安全认证、权限校验、分布式和持久化事务控制或向外部应用发送基于事件的消息等。
3、 领域层
领域层是软件的核心所在,它实现全部业务逻辑并且通过各种校验手段保证业务正确性。它包含业务所涉及的领域对象(实体、值对象)、领域服务以及它们之间的关系。它负责表达业务概念、业务状态以及业务规则,具体表现形式就是领域模型。
4、 基础层
基础层为各层提供通用的技术能力,包括:为应用层传递消息、提供API管理,为领域层提供数据库持久化机制。它还能通过技术框架来支持各层之间的交互。
四、 服务视图
(一)微服务内的服务视图
微服务内有Facade接口、应用服务、领域服务和基础服务,各层服务协同配合,为外部提供服务。
1、 接口服务
接口服务位于用户接口层,用于处理用户发送的Restful请求和解析用户输入的配置文件等,并将信息传递给应用层。
2、 应用服务
应用服务位于应用层。用来表述应用和用户行为,负责服务的组合、编排和转发,负责处理业务用例的执行顺序以及结果的拼装。
应用层的服务包括应用服务和领域事件相关服务。
应用服务可对微服务内的领域服务以及微服务外的应用服务进行组合和编排,或者对基础层如文件、缓存等数据直接操作形成应用服务,对外提供粗粒度的服务。
领域事件服务包括两类:领域事件的发布和订阅。通过事件总线和消息队列实现异步数据传输,实现微服务之间的解耦。
3、 领域服务
领域服务位于领域层,为完成领域中跨实体或值对象的操作转换而封装的服务,领域服务以与实体和值对象相同的方式参与实施过程。
领域服务对同一个实体的一个或多个方法进行组合和封装,或对多个不同实体的操作进行组合或编排,对外暴露成领域服务。领域服务封装了核心的业务逻辑。实体自身的行为在实体类内部实现,向上封装成领域服务暴露。
为隐藏领域层的业务逻辑实现,所有领域方法和服务等均须通过领域服务对外暴露。
为实现微服务内聚合之间的解耦,原则上禁止跨聚合的领域服务调用和跨聚合的数据相互关联。
4、 基础服务
基础服务位于基础层。为各层提供资源服务(如数据库、缓存等),实现各层的解耦,降低外部资源变化对业务逻辑的影响。
基础服务主要为仓储服务,通过依赖反转的方式为各层提供基础资源服务,领域服务和应用服务调用仓储服务接口,利用仓储实现持久化数据对象或直接访问基础资源。
(二)微服务外的服务视图
1. 前端应用与微服务
微服务中的应用服务通过用户接口层组装和数据转换后,发布在API网关,为前端应用提供数据展示服务。
2. 微服务与外部应用
跨微服务数据处理时,对实时性要求高的场景,可选择直接调用应用服务的方式(新增和修改类型操作需关注事务一致性)。对实时性要求不高的场景,可选择异步化的领域事件驱动机制(最终数据一致性)。
五、 数据视图
DDD分层架构中数据对象转换的过程如下图。
应用服务通过数据传输对象(DTO)完成外部数据交换。领域层通过领域对象(DO)作为领域实体和值对象的数据和行为载体。基础层利用持久化对象(PO)完成数据库的交换。
DTO与VO通过Restful协议实现JSON格式和对象转换。
前端应用与应用层之间DTO与DO的转换发生在用户接口层。如微服务内应用服务需调用外部微服务的应用服务,则DTO的组装和DTO