7.2 KiB
7.2 KiB
第31天:微服务架构——把大象拆成蚂蚁
今天你将学到什么
今天学习微服务架构的核心思想和 AWS 上的实现方式。理解为什么大公司都在从"一个大应用"转向"多个小服务",以及这样做的好处和挑战。
单体架构 vs 微服务架构
单体架构(Monolith)
所有功能都在一个应用里:
一个大应用:
├── 用户管理
├── 商品管理
├── 订单处理
├── 支付处理
├── 库存管理
├── 通知服务
└── 数据分析
类比:一家什么都卖的大超市。所有商品在一栋楼里,一个收银系统,一个仓库。
优点:
- 开发简单(一个代码库,一个部署)
- 本地调试方便
- 数据一致性容易保证
缺点:
- 代码越来越大,新人要几周才能理解
- 改一个小功能要重新部署整个应用
- 一个模块的 bug 可能拖垮整个系统
- 不同模块不能独立扩展(订单模块需要 10 台服务器,但用户模块只需要 2 台)
- 技术栈被锁定(整个应用必须用同一种语言)
微服务架构(Microservices)
每个功能是一个独立的小服务:
用户服务(Python)──┐
商品服务(Java)────┤
订单服务(Go)──────┼── 通过 API 互相通信
支付服务(Node.js)─┤
库存服务(Java)────┤
通知服务(Python)──┘
类比:一条商业街上的多家专卖店。鞋店只卖鞋,面包店只卖面包。每家店独立经营,互不影响。鞋店装修不影响面包店营业。
优点:
- 每个服务小而专注,容易理解和维护
- 独立部署(改了订单服务只需要重新部署订单服务)
- 独立扩展(订单服务压力大就多加几个实例)
- 技术自由(每个服务可以用最适合的语言和框架)
- 故障隔离(支付服务挂了,用户还能浏览商品)
缺点:
- 系统复杂度增加(服务间通信、数据一致性)
- 运维难度增加(几十个服务要监控)
- 调试困难(一个请求可能经过 5 个服务)
- 网络延迟(服务间调用比函数调用慢)
什么时候该用微服务
不要一开始就用微服务
马丁·福勒(微服务概念的推广者)说过:"几乎所有成功的微服务架构,都是从一个变得太大的单体应用演化而来的。"
判断标准
| 情况 | 建议 |
|---|---|
| 团队 < 5 人 | 单体架构 |
| 应用刚起步 | 单体架构 |
| 团队 > 20 人 | 考虑微服务 |
| 不同模块需要不同扩展策略 | 考虑微服务 |
| 部署频率需要很高 | 考虑微服务 |
| 单体已经大到难以维护 | 考虑微服务 |
微服务在 AWS 上的实现
服务运行方式
| 方式 | 适合 | AWS 服务 |
|---|---|---|
| 容器 | 长时间运行的服务 | ECS / EKS + Fargate |
| 无服务器 | 事件驱动、轻量服务 | Lambda + API Gateway |
| 虚拟机 | 遗留应用、特殊需求 | EC2 + Auto Scaling |
服务间通信
| 方式 | 适合 | AWS 服务 |
|---|---|---|
| 同步调用(HTTP/gRPC) | 需要立即得到结果 | ALB / API Gateway / App Mesh |
| 异步消息 | 不需要立即结果 | SQS / SNS / EventBridge |
| 事件流 | 实时数据流处理 | Kinesis / MSK(Kafka) |
服务发现
微服务之间怎么找到对方?
传统方式:把每个服务的地址写在配置文件里。服务地址变了就要改配置。
服务发现:服务启动时自动注册自己的地址,其他服务通过名字查找。
订单服务想调用用户服务:
→ 问服务发现:"用户服务在哪?"
→ 服务发现回答:"10.0.1.25:8080 和 10.0.1.26:8080"
→ 订单服务选一个调用
AWS 提供 Cloud Map 服务做服务发现。ECS 服务可以自动注册到 Cloud Map。
微服务的数据管理
每个服务拥有自己的数据库
这是微服务的核心原则之一:
❌ 错误:所有服务共享一个数据库
用户服务 ─┐
订单服务 ─┼── 同一个 MySQL 数据库
商品服务 ─┘
(一个服务改了表结构,其他服务可能崩溃)
✓ 正确:每个服务有自己的数据库
用户服务 → 用户数据库(RDS)
订单服务 → 订单数据库(DynamoDB)
商品服务 → 商品数据库(RDS)
(互不影响,可以选择最适合的数据库类型)
数据一致性挑战
当一个操作涉及多个服务时,如何保证数据一致?
举例:用户下单需要同时扣库存和创建订单。
解决方案:Saga 模式
1. 订单服务:创建订单(状态=待确认)
2. 库存服务:扣减库存
- 成功 → 订单服务:确认订单
- 失败 → 订单服务:取消订单(补偿操作)
每一步都有对应的"补偿操作"。如果某一步失败,执行前面所有步骤的补偿操作来回滚。
Step Functions 非常适合实现 Saga 模式。
微服务的可观测性
当一个请求经过 5 个服务时,出了问题怎么排查?
分布式追踪(AWS X-Ray)
X-Ray 可以追踪一个请求在多个服务间的完整路径:
用户请求 → API Gateway (5ms) → 订单服务 (20ms) → 库存服务 (15ms)
→ 支付服务 (200ms) ← 瓶颈在这里!
→ 通知服务 (10ms)
一眼就能看出哪个服务慢了、哪里出了错。
集中日志(CloudWatch Logs)
所有服务的日志发送到 CloudWatch Logs,统一查看和搜索。
统一监控(CloudWatch)
所有服务的指标(CPU、内存、请求量、错误率)在一个仪表板上展示。
微服务架构示例:电商平台
客户端
↓
API Gateway(统一入口)
├── /users → 用户服务(ECS Fargate)→ Aurora
├── /products → 商品服务(ECS Fargate)→ DynamoDB
├── /orders → 订单服务(ECS Fargate)→ Aurora
├── /payments → 支付服务(Lambda)→ 外部支付网关
└── /notifications → 通知服务(Lambda)→ SES/SNS
服务间通信:
订单服务 → SNS "订单创建" 事件
→ SQS → 库存服务(扣库存)
→ SQS → 通知服务(发通知)
→ SQS → 分析服务(记录数据)
服务发现:Cloud Map
分布式追踪:X-Ray
日志:CloudWatch Logs
监控:CloudWatch Dashboard
今天的小测验
- 单体架构和微服务架构各自的优缺点是什么?
- 什么时候应该从单体转向微服务?
- 微服务之间的同步通信和异步通信各自适合什么场景?
- 为什么每个微服务应该有自己的数据库?这带来了什么挑战?
延伸阅读
明天预告
明天是第四阶段的收尾:应用架构综合实战。我们会设计一个完整的微服务应用架构,把容器、CI/CD、API Gateway、Step Functions 等知识串联起来。