HiHuo
首页
博客
手册
工具
关于
首页
博客
手册
工具
关于
  • 微服务架构实战

    • 微服务架构设计手册
    • 第1章:微服务架构概述
    • 第2章:服务拆分与边界
    • 第3章:服务间通信
    • 第4章:数据一致性方案

第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
  • 本地消息表
  • 最终一致性

详见第4章:数据一致性方案


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│
└──────────────┘

步骤:

  1. 识别边界清晰的模块
  2. 提取为独立服务
  3. 逐步迁移流量
  4. 删除单体中的旧代码
  5. 重复以上步骤

策略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模式或本地消息表

详见第4章:数据一致性方案


微服务的运维复杂度如何解决?

答案:

工具链:

1. 容器化:
   Docker + Kubernetes
   - 标准化部署
   - 自动扩缩容
   - 滚动更新

2. CI/CD:
   Jenkins / GitLab CI
   - 自动化测试
   - 自动化部署
   - 蓝绿/金丝雀发布

3. 服务网格:
   Istio / Linkerd
   - 服务发现
   - 负载均衡
   - 熔断限流
   - 链路追踪

4. 监控:
   Prometheus + Grafana
   - 指标监控
   - 告警
   - 可视化

5. 日志:
   ELK Stack
   - 集中式日志
   - 日志搜索
   - 日志分析

6. 链路追踪:
   Jaeger / Zipkin
   - 分布式追踪
   - 性能分析

成熟度要求:

微服务不是银弹
需要团队具备:
- DevOps文化
- 自动化能力
- 监控能力
- 故障处理能力

Prev
微服务架构设计手册
Next
第2章:服务拆分与边界