穿越微服务迷雾:揭秘一次微服务设计实战

前言

最近学校课程要求做一个简单的微服务系统,正好借此机会拆解一下微服务系统的架构设计。

系统要求如下:

该基础业务平台应包含以下功能:

  1. 基于RBAC的系统权限管理功能,支持用户、角色和权限的可配置功能。在此基础上,实现基本的用户登录、注册等用户管理方面的功能。
  2. 提供统一的系统安全、缓存、日志、异常处理等功能接口。
  3. 提供统一的后台管理功能,可以对系统中的数据表进行后台管理。
  4. 在基础框架上,设计一个简单的业务场景(应至少涉及两个不同的角色、两个不同的业务部门),实现基本的业务功能。

平台的非功能方面的要求:

  1. 采用微服务架构:提供统一的服务网关、服务注册发现和服务间通信接口以及其他的服务管理方案。
  2. 采用前后端完全分离的架构。
  3. 兼容性要求:支持主流的浏览器,包括Chrome、Edge、Firefox和Safari。
  4. 安全性要求:系统达到等级保护二级要求,能够通过相应的安全性测试。
  5. 性能要求:系统应支持100并发,给出相应的测试结果。

单体架构

我们都知道单体项目的主流架构是分层架构,大概分为controller、service、dao、entity等层级,每个板块下可能会有多个业务类。但是单体项目中一个项目只有一个模块,所有的"包"都直接放在这个大模块中即可。

  • Controller层:
    • 作用: 负责接收用户的请求,调用相应的业务逻辑处理,并返回结果给用户。
    • 实现: 包含处理HTTP请求的逻辑,解析请求参数,调用Service层的业务逻辑,最后将结果返回给用户。
  • Service层:
    • 作用: 执行业务逻辑,处理业务规则和流程,对数据进行处理和组织。
    • 实现: 包含具体的业务逻辑,调用Dao层进行数据的读写,确保业务的正确执行。
  • Dao(Data Access Object)层:
    • 作用: 负责与数据库进行交互,执行数据的持久化操作。
    • 实现: 包含数据库操作的具体实现,例如SQL语句的增删改查等。
  • Entity层:
    • 作用: 表示业务领域中的实体,通常与数据库中的表结构相关。
    • 实现: 包含数据的定义,通常是一个与数据库表结构对应的Java类,类中的属性对应表中的字段。

首先我们来看看该项目的单体架构图,每层中的user、auth、business1、business2都是业务类

分模块+分层架构

然而该项目要求用微服务架构,微服务项目中通常需要按业务拆分出多个模块,那么项目架构是怎样的呢?

所以首先我们需要将该项目按业务分模块,那么就变为了分模块+分层架构。在微服务中还有两个要求:

  • gateway作为服务网关统一管理请求
  • 每个服务需要能调用其他服务模块,所以每个服务模块中还需要加上client这一层
  • 每个服务需要能提供服务模块给其他模块调用,所以每个服务模块中还需要加上api这一层

api层、client层、controller层各代表什么意思?

  • **api层:**提供给内部服务调用的一系列接口,属于被调用者
  • **client层:**主要负责发送HTTP请求需要调用的模块,可以理解为一个发送HTTP请求的封装层,属于调用者
  • **controller层:**提供给外部服务调用的一系 列接口,属于被调用者

api层与controller层的异同

  • **相同点:**都是提供HTTP接口给外部服务调用
  • **不同点:**controller层提供给外部服务(例如前端调用),而api层提供给内部服务调用,比如架构图中的其他服务

关系还是有点乱的,直接一图解千愁吧!

那么据此得来的架构图如下

这样是否就可行了呢?能用但问题大了,强烈不推荐:

极度高耦合:(1)A、B服务调用C服务时都需要写相同的client层(假设叫Cclient类),那么Cclient类需要复制两份分别在A、B服务中。(2)且Cclient类的方法返回值一定是C服务中的实体类(例如C服务是User服务那么可能是UserDO的数据库实体类),那么还需要将涉及到的所有实体类一并复制两份给A、B服务。

好家伙,一旦Capi相关的实体类有任何改动,那么Capi需要更改,调用C服务的Cclient代码中相关的实体类自然也全都需要修改,简直是灾难啊!

如何解决?

  1. 首先解决Cclient类需要复制两份的问题

    一个经典解法就是抽取模块,功能复用。将client层的代码给抽取出来写一个统一的HTTP请求服务工具,那么client层的代码就只需要引入工具调用即可,实现功能复用。不过还好,这个问题@FeignClient注解帮我们完成了,详情看这篇文章《Java远程调用神器:@FeignClient揭秘,轻松搞定微服务通信!》(Java远程调用神器:@FeignClient揭秘,轻松搞定微服务通信! - 掘金 (juejin.cn))

  2. 然后解决实体类需要复制两份的问题

    其实从这篇文章《Java远程调用神器:@FeignClient揭秘,轻松搞定微服务通信!》(Java远程调用神器:@FeignClient揭秘,轻松搞定微服务通信! - 掘金 (juejin.cn))中已经可以看出解决方法了,聪明如你,应该发现了client和api两个类几乎代码都一样。所以我们就可以想方法复用,将client继承api,然后client加上了@FeignClient注解即可,这就引出了微服务架构了

微服务架构

经过上面的分析,我们将上面提到的api以及相应的实体类抽取出来形成单独的模块,作为interface模块,那么另一个对应的就是service模块,即每一个业务对应的服务模块再分成interface和service模块,架构图及依赖关系如下

依赖关系使用Maven即可实现

xml 复制代码
	<!-- cloud-user-service的pom依赖 -->
    <dependencies>
        <dependency>
            <groupId>com.cloud.auth</groupId>
            <artifactId>cloud-auth-interface</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>
        ......
        <dependency>
            <groupId>com.cloud.common</groupId>
            <artifactId>cloud-common-web</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

结束了吗?到这里系统基本可用,没有大问题,但还是不太推荐,因为实体类全部放到interface模块中不太优雅。

在《阿里巴巴Java开发手册》中写到,实体类还分为DO、DTO、VO等等类型。

  • **DO:**与数据库表结构一一对应,通过 DAO 层向上传输数据源对象。

  • **DTO:**数据传输对象,Service 或 Manager 向外传输的对象。

  • **VO:**显示层对象,通常是 Web 向模板渲染引擎层传输的对象。

《阿里巴巴Java开发手册》可在公众号免费获取资源

一般常用到上面三种领域模型,这三种领域模型全放到interface模块中合适吗?

答案显然是否定的,DO类是与数据库一一映射的,只有dao层才会请求数据库返回DO类对象。而interface模块的目的是暴露出api给其他服务调用,那么api层更应该返回一个DTO对象而不会返回DO对象。那么也就是说interface模块一定不会需要用到DO类,于是我们得出结论:DO类应该在service模块中,而除了DO类的其他领域对象留在interface模块中,于是我们终于得到最终的架构图了!

如果您觉得该文章有用,欢迎点赞、留言并分享给更多人。感谢您的支持!

相关推荐
蝎子莱莱爱打怪2 天前
XZLL-IM干货系列 04|Netty 长连接实战:Pipeline 怎么排、心跳怎么跳、连接怎么管
后端·微服务·面试
SamDeepThinking3 天前
Java微服务练习方式
java·后端·微服务
米丘6 天前
微前端之 Web Components 完全指南
微服务·html
霸道流氓气质9 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
霸道流氓气质9 天前
Spring Boot 微服务性能优化完全指南
spring boot·微服务·性能优化
地瓜伯伯9 天前
从MESI缓存一致性协议讲透synchronized的底层
java·spring boot·spring·spring cloud·微服务·springcloud
Devin~Y9 天前
大厂 Java 面试实录:从音视频内容社区到 AI RAG 的全链路技术设计
java·spring boot·redis·spring cloud·微服务·kafka·音视频
递归尽头是星辰9 天前
AI 访问数据仓库:从直连到微服务化
数据仓库·人工智能·微服务·dataagent·ai数据治理
就改了9 天前
Windows 环境 SkyWalking 完整实操教程
windows·微服务·skywalking
至乐活着10 天前
Docker Compose多服务编排实战:从零搭建Node.js+MySQL+Redis全栈应用
docker·微服务·devops·容器编排·compose