ToB SaaS 平台架构演进:从单体到微服务的实战经验
在 ToB SaaS 领域,系统架构的演进是一个持续的过程。本文将分享我们从单体架构演进到微服务架构的实战经验,以及过程中踩过的坑。
架构演进路线
我们的架构演进经历了三个主要阶段:
单体应用 → 模块化单体 → 微服务架构
每次演进都是业务驱动,而非技术驱动。
第一阶段:单体应用(0-1 阶段)
特点
- 快速迭代,验证业务模式
- 开发效率高,部署简单
- 团队规模小(3-5人)
技术栈
- Spring Boot + MyBatis
- MySQL 单库
- Vue.js 前端
这个阶段的原则
能跑就行,先活下来
不要在 0-1 阶段过度设计,活下来才是最重要的。
第二阶段:模块化单体(1-10 阶段)
当业务增长,单体应用开始出现问题:
- 代码耦合严重,改一处影响多处
- 单次部署时间越来越长
- 团队协作困难
解决方案:模块化
├── common/ # 公共模块
├── user/ # 用户模块
├── order/ # 订单模块
├── product/ # 商品模块
├── payment/ # 支付模块
└── admin/ # 管理后台
关键改进
- 代码分层:明确模块边界
- 数据库分表:单表过大性能问题
- 缓存引入:Redis 缓存热点数据
- 消息队列:异步处理非核心逻辑
第三阶段:微服务架构(10-100 阶段)
当团队超过 10 人,业务复杂度持续增长,模块化单体也开始力不从心:
- 部署风险大,一个模块问题影响全局
- 扩展困难,无法针对性扩容
- 技术栈受限
微服务拆分原则
- 业务边界清晰:按领域拆分
- 数据独立:每个服务独立数据库
- 接口契约:API 先行设计
- 渐进式拆分:优先拆分变化频繁的模块
技术选型
| 组件 | 选型 | 原因 |
|---|---|---|
| 服务框架 | Spring Cloud | 生态完善,团队熟悉 |
| 注册中心 | Nacos | 配置中心一体化 |
| 网关 | Spring Cloud Gateway | 性能好,扩展性强 |
| 消息队列 | RabbitMQ | 可靠性优先 |
| 容器化 | Docker + K8s | 运维标准化 |
拆分后的架构
┌─────────────┐
│ Gateway │
└──────┬──────┘
│
┌──────────────────────┼──────────────────────┐
│ │ │
┌───▼───┐ ┌─────▼─────┐ ┌─────▼─────┐
│ User │ │ Order │ │ Product │
│Service│ │ Service │ │ Service │
└───┬───┘ └─────┬─────┘ └─────┬─────┘
│ │ │
┌───▼───┐ ┌─────▼─────┐ ┌─────▼─────┐
│User DB│ │ Order DB │ │Product DB │
└───────┘ └───────────┘ └───────────┘
踩过的坑
坑 1:过早微服务化
教训:团队只有 5 人时就搞微服务,运维成本急剧上升,得不偿失。
建议:团队 < 10 人,业务 < 10 个核心模块,不要急着上微服务。
坑 2:拆分粒度过细
教训:最开始拆了 20+ 个服务,服务间调用复杂,排查问题困难。
建议:宁可粗一点,后面再拆。合并容易,拆分难。
坑 3:分布式事务处理不当
教训:跨服务事务处理不当,导致数据不一致。
建议:
- 优先设计避免分布式事务
- 必要时用 Saga 模式
- 做好补偿机制
总结
架构演进没有银弹,核心原则是:
- 业务驱动:不为技术而技术
- 渐进式:小步快跑,持续演进
- 可逆性:保留回退能力
- 团队匹配:架构要与团队能力匹配
希望这些经验对你有帮助。下一篇将分享微服务下的监控与告警体系建设。