后端的四层架构
后端的四层分层架构
# 02.后端的分层架构
本文引用自:
1.我敢打赌,这个架构你一定知道!-腾讯云开发者社区-腾讯云 (opens new window)
2.00 后架构师,那可能么? (opens new window)
引用此文是作为笔者的摘录笔记
# 前言
开发后端项目时,最常见的架构模式就是分层架构。所谓的分层架构,就是把系统自上而下分为多个不同的层,每一层都有特定的功能和职责,且只和自己的直接上层与直接下层 “打交道”。
分层架构的优点是:每一层都有明确定义的职责,易于理解和维护;而且各层可以独立扩展,以适应不同的需求。
# 分层架构
以Java后端开发为例,Java 企业级后端项目开发时常用的分层架构,一般从前端界面**(表示层)发送的请求出发,需要经历接入层、控制层、业务逻辑层、通用业务层、数据访问层、系统资源层**等。
表示层 通常是指让用户交互和查看信息的前端界面,比如用户点击按钮后能够发送一个请求,也可以叫用户层、界面层等。
发送请求后,会经过 接入层 ,比如 Nginx 网关、或者其他中间件,对请求做一个预处理或转发,比如实现负载均衡。这一层不是必须存在的,通常更适用于中大型项目,前端也可以直接请求后端。
接入层会将请求转发到 控制层(Controller),负责接受请求、调用业务逻辑层(Service)的代码实现功能、然后响应结果。控制层一般不建议写复杂的业务逻辑,尽量保持精简。
接下来是 业务逻辑层(Service),负责处理复杂的业务逻辑,比如对请求数据进行校验、处理、调用数据访问层以将结果存到数据库中等,也是我们做系统时主要开发编码的部分。
通用业务层(Manager、Module)是一种特殊的业务逻辑层,主要的作用是抽取了一些需要被多个业务调用的公共代码,比如上传文件到对象存储、鉴权等,从而实现复用。
数据访问层(Dao / Mapper)负责操作底层的数据源,比如对数据库、文件、缓存等进行增删改查。
Data Access Object,数据访问对象
最后是 系统资源层 ,也可以叫基础设施层,包括各种基础服务、系统环境等,比如数据库、消息队列、Redis、文件存储、Linux 系统、Docker 等。复杂的基础设施可能还包括 K8S 容器资源编排、资源调度平台等。
因不同业务和团队选择,分层架构会有不同
比如开发 Java 企业级后端项目时常用的三层架构,将系统分为表示层、业务逻辑层、数据访问层。
表示层负责接受用户请求,把用户输入的参数传递给业务逻辑层进行处理,并返回数据、页面等内容给用户。
业务逻辑层负责处理复杂的业务逻辑,比如调用 AI 能力完成智能对话、再进行加工处理、调用数据访问层将结果存到数据库中,也是我们做系统主要开发的部分。
数据访问层负责操作底层的数据源,比如对数据库、文件、缓存等进行增删改查。
# 微服务架构
微服务的 “微” 是相对于 “单体” 项目的概念。微服务架构是指将完整的大型系统拆分为多个微小的、自治的服务,每个服务都能独立部署、独立扩展和维护、互不影响,服务之间通过网络通信进行协作,从而实现原本大型系统的完整功能。
我们首先将系统按照功能划分为了多个模块。但如果我们只是按逻辑划分出了这些模块,实际上所有的代码仍然部署在同一个项目中,打包后仍然是一个可执行文件。那么所有模块要么都在运行、要么都在宕机,本质上还是单体项目。一个服务崩了,可能导致整个项目都无法运行!

所以我们将部分重要模块(比如支付模块)的代码从原本项目中抽离,单独作为了一个服务,并且还启动了备份,从而保证了支付业务的稳定性。说什么也不能影响收入对不对~

能够实现微服务设计的框架也很多,比如 Java 的 Spring Cloud、Apache Dubbo 等。但是学习微服务更重要的是思想,即 如何合理地拆分服务 。
并不是所有的项目都要把所有功能都拆分成子服务的,像我们的鱼聪明 AI,也没有把用户模块和助手模块进行分离,原因是这两个模块的业务都不复杂、并且存在紧密的依赖,拆分后反而不利于维护了。
# 事件驱动架构
在事件驱动架构中,各模块之间是通过事件(或者消息)的 发布订阅模型 进行通信的。
举个最简单的例子,有两个模块:支付模块和会员模块,当用户支付成功后,支付模块会给会员模块发送一个 “XX 用户支付成功” 的事件,会员模块收到这个时间后,给对应的用户开通会员即可。

但实际运用时,事件驱动架构往往会引入一个 事件总线 ,相当于一个中介,负责集中收集和下发事件。
比如鱼聪明 AI 的对话功能和绘画功能就采用了事件驱动架构。当上游返回 AI 回复的消息或生成的图片后,会发送 “成功” 消息到事件总线,然后事件总线再将这些消息分别转发给对应的模块去处理。如下图:

这样一来,各模块之间就实现了解耦(互不影响)。假如后续我想新增多个对话模块,只要将该模块和事件总线建立连接即可,不会影响到其他模块的运行。
# 项目实践
比如 OJ 在线判题系统 ,分层架构如下:
# 示例项目结构
基于分层架构,我们可以将项目按照特定的目录名(包名)来组织代码,比如:
- controller:控制层
- service:业务逻辑层
- mapper:数据访问层
- model:数据模型
还可以按照业务或文件的类型来划分目录,比如:
- constant:常量
- annotation:注解类
- common:公共类
- config:配置类
- job:任务
- exception:异常处理相关
- utils:工具类
以之前带大家做过的为例,项目的目录结构如图:
(此图可以看出来教程是鱼皮写的)

# 其他知识
1)计算机网络也是采用了经典的分层架构,OSI 七层参考模型中,把计算机网络自底向上分为了物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。每个层只处理特定的功能,比如数据传输、数据的路由;层与层之间通过接口(或者叫协议)进行通信。
2)需要注意的是,我们常用的后端开发框架 Spring MVC 是基于 MVC(Model-View-Controller)设计模式构建的,而不能算是传统的分层架构。而且一般现在的项目中只使用 Spring MVC 作为整个项目的控制层,不过大多数用了 Spring MVC 框架的项目基本都使用了分层架构。
文字写于:广东