项目架构设计入门——从单体到微服务

项目架构设计入门——从单体到微服务

作者: CaoZH
日期: 2025-12-15
本文为原创教程


2025 年底,技术圈有个共识:只有被过度设计的架构,没有被过度设计的前两年。

很多团队一上来就上微服务 + K8s + 事件驱动,结果半年后连业务逻辑都没理顺。架构是服务于业务的,不是用来炫技的。

本文梳理从单体到微服务的架构演进路径,帮你判断当前项目适合什么架构。

一、架构演进路径

1
2
3
4
5
6
7
8
9
初创期                    成长期                    成熟期
│ │ │
▼ ▼ ▼
┌────────┐ ┌──────────────┐ ┌──────────────────┐
│ 单体架构 │ → │ 垂直拆分 │ → │ 微服务/分布式 │
│ │ │ │ │ │
│ 一个应用 │ │ 按模块拆为多个 │ │ 按业务拆为独立服务 │
│ 一个数据库 │ │ 独立部署 │ │ 独立数据库 + 消息 │
└────────┘ └──────────────┘ └──────────────────┘

二、单体架构

适用场景

  • 团队 1-5 人
  • 项目启动初期
  • 业务逻辑简单
  • 需要快速验证市场

项目结构

1
2
3
4
5
6
7
8
9
10
11
12
my-app/
├── src/main/java/com/example/
│ ├── controller/ # 控制层
│ ├── service/ # 业务层
│ ├── repository/ # 数据层
│ ├── entity/ # 实体
│ ├── dto/ # 数据传输对象
│ ├── config/ # 配置
│ └── utils/ # 工具
├── src/main/resources/
│ └── application.yml
└── pom.xml

优势与劣势

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
## 优势
✅ 开发简单,学习成本低
✅ 部署简单,一个 JAR/WAR 搞定
✅ 调试方便,本地直接运行
✅ 事务管理简单
✅ 测试容易

## 劣势
❌ 代码量增大后难以维护
❌ 无法独立扩展某个模块
❌ 构建和部署时间会变长
❌ 技术栈被锁定
❌ 团队协作冲突多

## 什么时候拆?
- 代码量 > 10 万行
- 团队 > 10 人
- 构建时间 > 10 分钟
- 某个模块需要独立扩缩容

三、垂直拆分

当单体越来越大时,第一步不是上微服务,而是垂直拆分

拆分方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
┌─────────────────────────────────────┐
│ 单体应用 │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │ 用户 │ │ 订单 │ │ 商品 │ │ 支付 │ │
│ └──────┘ └──────┘ └──────┘ └──────┘ │
└─────────────────────────────────────┘
│ 按模块拆分

┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐
│用户服务│ │订单服务│ │商品服务│ │支付服务│
│ JAR │ │ JAR │ │ JAR │ │ JAR │
└──┬───┘ └──┬───┘ └──┬───┘ └──┬───┘
│ │ │ │
┌──▼──────────▼──────────▼──────────▼──┐
│ 共用一个数据库 │
└──────────────────────────────────────┘

典型拆分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 按业务模块拆分为多个应用
services:
user-service: # 用户服务
build: ./user-service
port: 8081
database: 共用

order-service: # 订单服务
build: ./order-service
port: 8082
database: 共用

gateway: # API 网关
build: ./gateway
port: 80

四、微服务架构

适用场景

  • 团队 > 20 人
  • 业务逻辑复杂
  • 不同模块需要独立扩缩容
  • 需要独立技术栈选型

完整架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
┌─────────────────────────────────────────┐
│ 客户端(Web/App) │
└────────────────┬────────────────────────┘

┌────────────────▼────────────────────────┐
│ API Gateway(网关) │
│ 路由 / 认证 / 限流 / 日志 │
└──┬──────┬──────┬──────┬──────┬─────────┘
│ │ │ │ │
┌──▼──┐ ┌▼───┐ ┌▼───┐ ┌▼───┐ ┌▼───────┐
│用户 │ │订单 │ │商品 │ │支付 │ │ 通知 │
│服务 │ │服务 │ │服务 │ │服务 │ │ 服务 │
└──┬──┘ └──┬─┘ └──┬─┘ └──┬─┘ └──┬─────┘
│ │ │ │ │
┌──▼───────▼──────▼──────▼──────▼───────┐
│ 消息队列(RabbitMQ/Kafka) │
└────────────────────────────────────────┘
│ │ │ │ │
┌──▼───────▼──────▼──────▼──────▼───────┐
│ 数据库集群 │
│ 用户DB 订单DB 商品DB 支付DB │
└────────────────────────────────────────┘

关键组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# docker-compose 微服务示例
services:
# 注册中心
nacos:
image: nacos/nacos-server:v2.3
ports:
- "8848:8848"

# API 网关
gateway:
build: ./gateway
ports:
- "80:8080"
depends_on: [nacos]

# 业务服务
user-service:
build: ./user-service
depends_on: [nacos, mysql, redis]
environment:
SPRING_CLOUD_NACOS_DISCOVERY_SERVER-ADDR: nacos:8848

order-service:
build: ./order-service
depends_on: [nacos, mysql, redis, rabbitmq]

# 消息队列
rabbitmq:
image: rabbitmq:3-management
ports:
- "5672:5672"
- "15672:15672"

五、数据库拆分策略

1
2
3
4
5
6
7
8
9
10
11
12
13
## 阶段一:共用数据库
所有服务连同一个数据库,但按 schema/表前缀隔离

## 阶段二:读写分离
主库写入,从库读取,缓解数据库压力

## 阶段三:分库分表
按业务拆分数据库,每个服务有自己的数据库
大表按 ID/时间分片

## 阶段四:分布式数据库
引入 TiDB/OceanBase 等原生分布式数据库
对应用层透明,不需要手动分片

六、架构设计原则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
## 1. 高内聚低耦合
- 相关功能放在同一个模块
- 模块间通过接口通信,不直接依赖实现

## 2. 单一职责
- 一个服务只做一件事
- 改动一个功能不需要修改多个服务

## 3. 渐进式演进
- 先单体 → 再垂直拆分 → 再微服务
- 不要为了用微服务而用微服务

## 4. 容错设计
- 熔断(Circuit Breaker)
- 降级(Fallback)
- 限流(Rate Limiting)
- 重试(Retry)

## 5. 可观测性
- 日志(Logging):ELK / Loki
- 指标(Metrics):Prometheus + Grafana
- 链路追踪(Tracing):SkyWalking / Jaeger

七、总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
## 架构选型决策树

项目初期(<5人 / <6个月)

单体架构 ✅

项目增长(10+人 / 代码10万行+)

垂直拆分 ✅

业务复杂(20+人 / 模块独立扩缩容需求)

微服务 ✅

## 记住这条原则

没有最好的架构,只有最适合当前阶段的架构。
过早的微服务化是万恶之源。

首发于 CaoZH 的笔记