跳转至

🏛️ 后端架构模式(从单体到微服务全景)

学完具体 API 后,需要一层的"全局视野":后端项目是怎么组织起来的?REST / 分层 / 单体 / 微服务 / 消息驱动分别解决什么?本篇帮你在动手前先建立架构心智模型,避免"会写接口却不懂怎么搭项目"。

依据 Microsoft 架构指南Martin Fowler 架构文集12-Factor App


一、分层架构(最基础、必懂)

绝大多数后端项目都是分层的,请求自上而下穿过各层,每层只依赖下一层:

Controller(接请求/返回响应)
   ↓
Service(业务逻辑,核心)
   ↓
Repository / DAO(操作数据库)
   ↓
Database
  • Controller:薄,只做参数解析、调用 Service、包装响应。不写业务
  • Service:业务逻辑都在这里,可单测、可复用。
  • Repository:封装数据访问,屏蔽 SQL/ORM 细节。

分层反模式

  • Controller 写业务:逻辑散在控制器里,无法复用、无法单测。
  • Service 直接 req/res:业务层依赖 HTTP 框架,换传输层(如加 CLI/队列消费)就废了。Service 应只吃参数、吐数据。
  • 跨层调用:Service 直接查 HTTP 头、Controller 直接 repo.save,破坏分层,后期重构痛。

二、RESTful API 设计

REST 是当前最主流的 HTTP 接口风格:用 资源(名词)+ HTTP 方法(动词) 表达操作。

方法 含义 示例
GET 查(幂等、安全) GET /users/1
POST 增(非幂等) POST /users
PUT 整体改(幂等) PUT /users/1
PATCH 局部改(幂等) PATCH /users/1
DELETE 删(幂等) DELETE /users/1

REST 设计要点

  • URL 用复数名词资源:/users 而非 /getUser;动作交给 HTTP 方法。
  • 状态码表意:200 成功、201 创建、204 无内容、400 参数错、401 未登录、403 无权限、404 不存在、500 服务端错。
  • 分页/过滤用 query:GET /users?page=1&size=20&role=admin
  • 版本化:/api/v1/users,方便不破坏旧客户端地升级。

REST 常见错误

  • 用 GET 做删除/修改(GET 应安全幂等,浏览器/代理可能预取、缓存,导致误删)。
  • 把所有操作塞成 POST /doSomething,退化成 RPC,失去 REST 可预测性。
  • 状态码永远 200,错误塞在 {code:500},前端只能解析 body,缓存/重试语义全乱。

三、单体(Monolith)vs 微服务(Microservices)

维度 单体 微服务
部署 一个包一次部署 多个服务独立部署
团队 小团队友好 多团队并行
复杂度 代码耦合风险 分布式复杂度(网络/事务/追踪)
扩展 整体扩容 按需扩热点服务
适合 绝大多数项目、MVP、中小团队 大型、需独立扩容/独立技术栈

微服务决策红线

  • 康威定律:微服务边界 = 团队边界。团队没拆分,强行拆服务只会内耗。
  • 模块化单体(Nest 的 Module 就是天然边界),等真的遇到"某模块要独立扩容 / 独立技术栈 / 团队大了"再拆。
  • 微服务引入:服务发现、配置中心、分布式事务(Saga)、链路追踪、网关——每一项都是新运维负担。

四、消息驱动 / 事件驱动架构

消息队列(Kafka/RabbitMQ/NATS)解耦生产者与消费者:

订单服务 → [下单事件] → 消息队列 → 邮件服务 / 库存服务 / 积分服务
  • 好处:下单主流程不被"发邮件、减库存"拖慢;某个消费者挂了,消息不丢、恢复后补处理。
  • NestJS 进阶·队列 对应(BullMQ 是进程内队列,Kafka 是跨服务消息总线)。

何时用消息驱动

  • 一个动作要触发多个后续副作用(下单→通知+扣库存+算积分)。
  • 需要削峰(秒杀、批量导入)。
  • 需要最终一致性而非强一致事务。
  • 消费者必须幂等:同一条消息重投不能重复扣款/重复发邮件。

五、MVC / CQRS / 六边形(了解即可)

  • MVC:Model(数据)+ View(视图)+ Controller(控制),早期 Web 全栈形态;后端 API 时代 View 退化为 JSON。
  • CQRS(命令与查询职责分离):写模型和读模型分开,复杂读场景(报表/搜索)单独优化。高复杂度才上。
  • 六边形架构(端口与适配器):业务逻辑在中心,外部(HTTP/DB/消息)通过"端口"接入,便于替换实现、利于测试。Nest 的 Provider/Interface 思路与之契合。

学习建议

新人先把分层 + REST + 模块化单体吃透,这覆盖了 90% 项目。CQRS/六边形是"遇到问题再引入"的进阶工具,不要提前过度设计。


六、一张图统筹:你的后端长什么样

            ┌─────────────┐
   前端 ───▶ │  反向代理   │ (Nginx: TLS/限流/静态)
            └──────┬──────┘
                   ▼
            ┌─────────────┐
            │  Web 框架   │ (Express/Nest: 路由/中间件/Guard)
            │  分层架构    │
            │  Controller │
            │  Service    │ ← 业务逻辑核心
            │  Repository │
            └──┬─────┬───┘
               ▼     ▼
         ┌────────┐ ┌─────────┐
         │  DB    │ │  Redis  │ (缓存/队列/会话)
         └────────┘ └─────────┘
               │
         ┌─────┴──────┐
         │ 消息队列    │ → 异步消费者/微服务
         └────────────┘