Skip to content

一、项目整体架构

如果你只做过前端,可以把"微服务架构"想象成—— 你把一个巨大的 Monorepo 拆成了好几个独立部署的应用,它们各自有自己的端口、数据库,彼此之间像前端调后端一样通过 HTTP / 消息队列通信。

1.1 技术栈一句话概括

  • 框架:Spring Cloud 微服务(Spring Boot + Spring Cloud)
  • 语言:Java 17
  • 数据库:MongoDB(主库,存业务数据)+ MySQL(辅助统计分析)
  • 缓存:Redis
  • 消息队列:RocketMQ
  • 对象存储:OSS(云端文件存储)
  • 部署:Docker / Kubernetes

1.2 用前端术语理解后端概念

如果你已经做过 React / Vue / Next.js 项目,这张表可以帮你快速建立映射:

后端概念前端类比在项目中长什么样
微服务把一个大型 Monorepo 拆成多个可独立部署的应用gateway、user-service、ai-service 等各自独立启动
网关 (Gateway)Nginx 反向代理 / 前端 BFF 统一入口所有外部请求先到网关,再转发到具体服务
Feign Client封装好的 axios 实例,调用远端接口就像调本地函数在共享 API 模块中声明接口,自动发 HTTP 请求
ControllerNext.js 的 app/api/ 路由 / Express 的 router.get()每个服务的 controller/ 目录
Service前端 service 层 / 业务逻辑 composable / hook每个服务的 service/ 目录
Repository前端对 localStorage / IndexedDB 的读写封装每个服务的 repository/ 目录
DTO / VOTypeScript 的 interface / typedto/vo/ 目录中的 Java 类
消息队列 (MQ)EventBus / Redux middleware / postMessageRocketMQ——发一条消息出去,另一个服务在后台消费
Redis 缓存浏览器 sessionStorage / 前端内存缓存速度快、常用于限流、缓存、分布式锁
组件模块 (component/)@org/utils@org/http-client 等共享 npm 包component/ 下的各种 cpt-* 基础模块

1.3 服务拆分总览

一个典型的 Spring Cloud 微服务项目长这样:

text
project-root (父工程,类似 Monorepo 根目录)

├── component/               ← 共享基础组件(类比你的 packages/ 或 libs/)
│   ├── cpt-api              ← 所有服务间调用的客户端 + 共享 DTO
│   ├── cpt-common           ← 通用工具类、统一响应格式
│   ├── cpt-mongodb          ← MongoDB 连接与操作封装
│   ├── cpt-mysql            ← MySQL 连接与 ORM 封装
│   ├── cpt-redis            ← Redis 缓存封装
│   ├── cpt-rocketmq         ← 消息队列封装
│   └── cpt-xxljob           ← 定时任务框架

├── svc-gateway              ← API 网关(唯一对外暴露的入口)
├── svc-auth                 ← 认证服务(登录 / token 颁发与校验)
├── svc-user                 ← 用户服务(注册 / 登录 / 配额 / 支付)
├── svc-ai                   ← AI 服务(图片生成 / 文字处理 / 人脸检测)
├── svc-canvas               ← 画布服务(模板 / 作图 / 任务编排,最复杂)
├── svc-oss                  ← 文件存储服务(上传 / 下载 / 云 OSS)
└── svc-admin                ← 管理后台(后台管理 / 数据统计)

💡 前端类比component/ 就像你的 packages/shared,而 svc-* 就像 apps/webapps/admin 等可独立部署的应用。

1.4 三种服务间通信方式

微服务之间怎么"说话"?这个项目用了三种方式:

通信方式用途前端类比什么时候用
HTTP (Feign)服务之间同步调用axios.get('/api/xxx')需要立刻拿到结果的场景(如查询用户信息)
RocketMQ 消息队列异步耗时任务postMessage + Web Worker不需要立刻拿到结果(如提交 AI 生图任务)
Redis缓存 + 分布式锁localStorage + 简易互斥锁需要缓存热数据或防并发的场景

关于服务发现

你可能听说过"注册中心"(Nacos、Eureka)。在容器化部署(Docker / K8s)环境下,更常见的做法是 DNS 直连——每个服务通过容器名就能找到对方,不需要额外的注册中心。

yaml
# 示意:Feign 客户端的服务地址配置
@FeignClient(name = "ai-service", url = "${service.ai.url}")
# 实际运行时 service.ai.url 由环境变量注入,如 http://ai-service:8080

1.5 网关的作用(重点理解)

网关好比大楼的前台,所有外部请求必须经过它,它负责四件事:

text
客户端请求


┌──────────────────────────────────┐
│          API 网关 (Gateway)       │
│                                  │
│  1. 路由转发                      │
│     /api/user/** → 用户服务       │
│     /api/ai/**   → AI 服务        │
│     /api/oss/**  → 存储服务       │
│                                  │
│  2. 身份认证                      │
│     读取 token → 调认证服务校验    │
│     白名单路径跳过认证             │
│                                  │
│  3. 限流                          │
│     基于 Redis 计数器限频          │
│                                  │
│  4. 熔断                          │
│     某服务不可用时快速失败          │
│     防止拖垮整个系统               │
└──────────────────────────────────┘


  目标微服务

前端类比:你可以把网关理解为一个"超级 Nginx",它除了做反向代理(路由转发),还内置了登录校验中间件、限流中间件、熔断中间件。