第1章:微服务架构概述
单体架构 vs 微服务架构
单体架构(Monolithic Architecture)
定义:所有功能模块部署在同一个进程中的应用程序
典型结构:
┌─────────────────────────────────────┐
│ Monolithic Application │
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │ UI │ │ API │ │
│ └──────────┘ └──────────┘ │
│ │
│ ┌─────────────────────────┐ │
│ │ Business Logic │ │
│ │ - User Module │ │
│ │ - Order Module │ │
│ │ - Product Module │ │
│ │ - Payment Module │ │
│ └─────────────────────────┘ │
│ │
│ ┌─────────────────────────┐ │
│ │ Data Access Layer │ │
│ └─────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────┐ │
│ │ Database │ │
│ └─────────────────────────┘ │
└─────────────────────────────────────┘
部署:整个应用作为一个单元部署
优点:
- 开发简单:统一技术栈,开发工具链成熟
- 测试容易:端到端测试直接运行
- 部署简单:一个war/jar包部署
- 性能好:进程内调用,无网络开销
- 事务简单:数据库事务保证ACID
缺点:
- 扩展困难:只能整体扩展,无法针对某个模块
- 技术锁定:难以引入新技术栈
- 部署风险:局部修改需要整体部署
- 团队协作:代码耦合,多团队开发困难
- 故障影响大:一个模块问题影响整个应用
微服务架构(Microservices Architecture)
定义:将应用拆分为一组小型、独立部署的服务,每个服务运行在自己的进程中
典型结构:
┌──────────────────────────────────────────┐
│ API Gateway │
└──────────────────────────────────────────┘
↓ ↓ ↓ ↓
┌──────────┐┌──────────┐┌──────────┐┌──────────┐
│ User ││ Order ││ Product ││ Payment │
│ Service ││ Service ││ Service ││ Service │
└──────────┘└──────────┘└──────────┘└──────────┘
↓ ↓ ↓ ↓
┌─────────┐┌─────────┐┌─────────┐┌─────────┐
│ User DB ││Order DB ││Product ││Payment │
│ ││ ││ DB ││ DB │
└─────────┘└─────────┘└─────────┘└─────────┘
每个服务:
- 独立进程
- 独立数据库
- 独立部署
- 通过API通信
优点:
- 独立部署:服务可单独部署,降低风险
- 技术多样性:每个服务可选择最适合的技术
- 独立扩展:按需扩展特定服务
- 团队自治:小团队负责完整服务
- 故障隔离:单个服务故障不影响整体
缺点:
- 复杂性高:分布式系统固有复杂性
- 数据一致性:跨服务事务困难
- 网络延迟:服务间网络调用
- 运维成本:需要自动化部署、监控
- 测试困难:端到端测试复杂
微服务的核心特征
1. 服务组件化(Componentization via Services)
传统组件化:
Application
├── user.jar
├── order.jar
└── product.jar
问题:
- jar包在同一进程
- 无法独立部署
- 共享内存
微服务组件化:
User Service (独立进程) ←→ HTTP/gRPC
Order Service (独立进程)
Product Service (独立进程)
优势:
独立进程,隔离性强
独立部署
明确接口边界
2. 按业务能力组织(Organized around Business Capabilities)
传统分层组织:
┌─────────────────────┐
│ UI Team │
├─────────────────────┤
│ Backend Team │
├─────────────────────┤
│ DBA Team │
└─────────────────────┘
问题:
跨团队协作频繁
职责不清晰
效率低
微服务组织:
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ User Team │ │ Order Team │ │Product Team │
│ ┌────────┐ │ │ ┌────────┐ │ │ ┌────────┐ │
│ │ UI │ │ │ │ UI │ │ │ │ UI │ │
│ │Backend │ │ │ │Backend │ │ │ │Backend │ │
│ │ DB │ │ │ │ DB │ │ │ │ DB │ │
│ └────────┘ │ │ └────────┘ │ │ └────────┘ │
└──────────────┘ └──────────────┘ └──────────────┘
优势:
团队职责清晰(端到端)
快速响应业务需求
减少跨团队依赖
3. 产品化思维(Products not Projects)
传统项目思维:
开发 → 交付 → 运维接手 → 团队解散
问题:
"扔过墙"文化
缺乏持续改进
产品化思维:
开发团队 = 运维团队
"You build it, you run it"
优势:
团队对服务全生命周期负责
持续优化
快速响应问题
4. 智能端点和哑管道(Smart endpoints and dumb pipes)
传统ESB(Enterprise Service Bus):
Service A → ESB(复杂路由、转换、编排)→ Service B
问题:
ESB成为中心依赖
逻辑分散
微服务通信:
Service A ─REST/gRPC→ Service B
特点:
服务自身处理业务逻辑
通信协议简单(HTTP、消息队列)
无中心化组件
5. 去中心化治理(Decentralized Governance)
技术多样性:
User Service → Go + PostgreSQL
Order Service → Java + MySQL
Product Service → Node.js + MongoDB
每个团队选择最适合的技术栈
6. 去中心化数据管理(Decentralized Data Management)
单体架构:
┌──────────────────┐
│ Shared Database │
│ - users │
│ - orders │
│ - products │
└──────────────────┘
↑ ↑ ↑
所有模块共享
微服务架构:
User Service → User DB
Order Service → Order DB
Product Service → Product DB
优势:
服务自治
schema独立演进
技术选型灵活
挑战:
数据一致性(需要分布式事务)
7. 基础设施自动化(Infrastructure Automation)
必需工具:
┌────────────────────────────────┐
│ CI/CD Pipeline │
│ - 自动化测试 │
│ - 自动化部署 │
│ - 蓝绿部署/金丝雀发布 │
└────────────────────────────────┘
┌────────────────────────────────┐
│ Container Orchestration │
│ - Kubernetes │
│ - Docker Swarm │
└────────────────────────────────┘
┌────────────────────────────────┐
│ Monitoring & Logging │
│ - Prometheus + Grafana │
│ - ELK Stack │
│ - Distributed Tracing │
└────────────────────────────────┘
8. 容错设计(Design for failure)
微服务必须假设故障会发生:
// 超时控制
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
resp, err := client.Get(ctx, url)
if err != nil {
// 降级处理
return getFromCache()
}
// 熔断器
circuitBreaker.Call(func() error {
return callService()
})
// 重试
retry.Do(func() error {
return callService()
}, retry.Attempts(3))
9. 演进式设计(Evolutionary Design)
持续演进:
V1: 单体应用
↓
V2: 拆分用户服务
↓
V3: 拆分订单服务
↓
V4: 拆分支付服务
...
逐步演进,而非一次性重写
微服务的挑战
1. 分布式系统复杂性
问题:
单体:方法调用(纳秒级)
微服务:网络调用(毫秒级)
新增问题:
- 网络延迟
- 网络故障
- 消息丢失
- 消息乱序
解决:
- 超时控制
- 重试机制
- 熔断降级
- 幂等设计
2. 数据一致性
问题:
单体:数据库事务(ACID)
微服务:分布式事务(?)
场景:订单创建需要:
1. 创建订单(Order Service)
2. 扣减库存(Inventory Service)
3. 扣减余额(Payment Service)
如何保证一致性?
解决:
- Saga模式
- TCC
- 本地消息表
- 最终一致性
3. 运维复杂度
问题:
单体:1个应用
微服务:N个服务(N可能是几十甚至上百)
运维挑战:
- 部署(N个服务)
- 监控(N个服务)
- 日志(分散在N个服务)
- 链路追踪(跨N个服务)
解决:
- CI/CD自动化
- 容器化(Docker + Kubernetes)
- 集中式日志(ELK)
- 分布式追踪(Jaeger、Zipkin)
- 服务网格(Istio)
4. 测试复杂度
问题:
单体:启动一个应用,端到端测试
微服务:需要启动N个服务,依赖复杂
示例:测试订单创建
需要:Order Service + Inventory Service + Payment Service + User Service
解决:
- 契约测试(Pact)
- 服务虚拟化(Mock)
- 测试环境隔离
适用场景
何时使用微服务
适合微服务:
大型复杂应用(团队 > 10人)
需要快速迭代
不同模块有不同扩展需求
团队成熟(DevOps能力强)
业务相对稳定(边界清晰)
示例:
- 电商平台(淘宝、京东)
- 社交网络(Facebook、Twitter)
- 视频平台(Netflix、YouTube)
不适合微服务:
小型应用(团队 < 5人)
初创公司(业务未验证)
简单CRUD应用
团队DevOps能力弱
业务频繁变化(边界不清)
示例:
- 简单博客系统
- 内部管理系统
- MVP产品
演进策略
从单体到微服务的迁移路径
策略1:绞杀者模式(Strangler Fig Pattern)
阶段1:单体 + 新功能用微服务
┌──────────────┐ ┌──────────────┐
│ Monolith │ │New Feature │
│ │ │(Microservice)│
└──────────────┘ └──────────────┘
阶段2:逐步迁移模块
┌──────────────┐ ┌──────────────┐
│ Monolith │ │User Service │
│ (部分功能) │ ├──────────────┤
│ │ │Order Service │
└──────────────┘ └──────────────┘
阶段3:完全微服务化
┌──────────────┐
│User Service │
├──────────────┤
│Order Service │
├──────────────┤
│Product Service│
└──────────────┘
步骤:
- 识别边界清晰的模块
- 提取为独立服务
- 逐步迁移流量
- 删除单体中的旧代码
- 重复以上步骤
策略2:分支抽象(Branch by Abstraction)
// 1. 抽象层
type UserRepository interface {
FindByID(id string) (*User, error)
}
// 2. 单体实现
type MonolithUserRepo struct {
db *sql.DB
}
func (r *MonolithUserRepo) FindByID(id string) (*User, error) {
// 查询单体数据库
}
// 3. 微服务实现
type MicroserviceUserRepo struct {
client *http.Client
}
func (r *MicroserviceUserRepo) FindByID(id string) (*User, error) {
// 调用微服务API
}
// 4. 通过配置切换
func NewUserRepository(useMicroservice bool) UserRepository {
if useMicroservice {
return &MicroserviceUserRepo{}
}
return &MonolithUserRepo{}
}
// 5. 灰度发布
// 10%流量 → 微服务
// 90%流量 → 单体
策略3:API网关路由
┌────────────┐
│API Gateway │
└────────────┘
↓
┌───┴───┐
↓ ↓
单体 微服务
路由规则:
/api/users/* → User Microservice
/api/orders/* → Order Microservice
/* → Monolith (默认)
逐步将路由指向微服务
面试问答
什么时候应该使用微服务架构?
答案:
应该使用微服务:
1. 团队规模 > 10人
2. 应用复杂度高
3. 需要快速迭代
4. 不同模块扩展需求不同
5. 团队DevOps成熟
示例:Netflix、Amazon
不应该使用微服务:
1. 团队 < 5人
2. 初创公司(业务未验证)
3. 简单CRUD应用
4. 缺乏自动化能力
示例:简单博客、内部工具
判断标准:
问自己3个问题:
1. 团队是否有DevOps能力?
2. 应用是否足够复杂?
3. 业务边界是否清晰?
3个都是"是" → 考虑微服务
否则 → 单体更合适
微服务和SOA有什么区别?
答案:
| 对比维度 | SOA | 微服务 |
|---|---|---|
| 粒度 | 粗粒度(企业级服务) | 细粒度(单一职责) |
| 通信 | ESB(重量级) | REST/gRPC(轻量级) |
| 数据 | 共享数据库 | 每个服务独立数据库 |
| 治理 | 中心化 | 去中心化 |
| 部署 | 一起部署 | 独立部署 |
| 技术栈 | 统一 | 多样化 |
核心区别:
SOA:企业级服务集成(重量级)
微服务:轻量级、独立自治的服务(现代化)
如何确定微服务的边界?
答案:
原则:
1. 单一职责原则(SRP)
每个服务只做一件事
2. 高内聚、低耦合
相关功能聚集在一起
服务间依赖最小化
3. DDD限界上下文
按业务领域划分
实践方法:
1. 按业务能力划分:
User Service(用户管理)
Order Service(订单管理)
Product Service(商品管理)
Controller Service
Database Service
2. 按子域划分(DDD):
核心域、支撑域、通用域
3. 数据边界:
独立数据库 = 服务边界
微服务如何保证数据一致性?
答案:
问题场景:
订单创建需要:
1. 创建订单(Order Service)
2. 扣减库存(Inventory Service)
3. 扣减余额(Payment Service)
如何保证3个操作的一致性?
方案对比:
| 方案 | 一致性 | 性能 | 复杂度 | 推荐度 |
|---|---|---|---|---|
| 2PC | 强一致 | 差 | 高 | |
| Saga | 最终一致 | 好 | 中 | |
| TCC | 最终一致 | 好 | 高 | 适用于金融 |
| 本地消息表 | 最终一致 | 好 | 低 |
推荐:Saga模式或本地消息表
微服务的运维复杂度如何解决?
答案:
工具链:
1. 容器化:
Docker + Kubernetes
- 标准化部署
- 自动扩缩容
- 滚动更新
2. CI/CD:
Jenkins / GitLab CI
- 自动化测试
- 自动化部署
- 蓝绿/金丝雀发布
3. 服务网格:
Istio / Linkerd
- 服务发现
- 负载均衡
- 熔断限流
- 链路追踪
4. 监控:
Prometheus + Grafana
- 指标监控
- 告警
- 可视化
5. 日志:
ELK Stack
- 集中式日志
- 日志搜索
- 日志分析
6. 链路追踪:
Jaeger / Zipkin
- 分布式追踪
- 性能分析
成熟度要求:
微服务不是银弹
需要团队具备:
- DevOps文化
- 自动化能力
- 监控能力
- 故障处理能力