跳转至

第一章:微服务概述与单体到微服务演进

1.1 什么是微服务架构

微服务架构(Microservices Architecture)是一种将单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,服务间通过轻量级机制(通常是 HTTP API)通信。

微服务的核心特征

  1. 服务自治:每个服务可以独立开发、测试、部署和扩展
  2. 业务边界清晰:按业务能力划分服务边界
  3. 去中心化:数据管理去中心化,每个服务管理自己的数据库
  4. 技术多样性:不同服务可以使用不同的技术栈
  5. 弹性设计:为失败而设计,具备容错能力

微服务与单体架构对比

维度 单体架构 微服务架构
代码组织 统一代码库 多个独立代码库
部署方式 整体部署 独立部署
扩展方式 垂直扩展 水平扩展
技术栈 统一技术栈 可多样化
故障影响 全局影响 局部影响
开发复杂度 初期简单 初期复杂
运维复杂度 相对简单 较高

1.2 微服务架构的优势

1. 独立部署

每个服务可以独立部署,不影响其他服务:

# 单体架构 - 部署整个应用
kubectl apply -f monolith-app.yaml

# 微服务架构 - 只部署变更的服务
kubectl apply -f user-service.yaml
kubectl apply -f order-service.yaml

2. 技术选型灵活

不同服务可以根据需求选择最适合的技术:

用户服务 → Python + FastAPI(快速开发)
推荐服务 → Python + TensorFlow(机器学习)
支付服务 → Java + Spring(企业级稳定)
前端服务 → Node.js + Next.js(SSR)

3. 独立扩展

根据服务负载独立扩展:

# Kubernetes HPA 配置示例
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: order-service-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: order-service
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

4. 故障隔离

单个服务的故障不会导致整个系统崩溃:

# 使用熔断器隔离故障
from circuitbreaker import circuit

@circuit(failure_threshold=5, recovery_timeout=30)
def call_payment_service(order_id):
    # 如果支付服务故障,熔断器会快速失败
    # 避免级联故障
    return payment_client.process(order_id)

1.3 微服务架构的挑战

1. 分布式系统的复杂性

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│   服务 A    │────→│   服务 B    │────→│   服务 C    │
└─────────────┘     └─────────────┘     └─────────────┘
      ↓                   ↓                   ↓
   网络延迟            服务发现            数据一致性
   网络分区            负载均衡            分布式事务
   服务故障            配置管理            链路追踪

2. 数据一致性挑战

# 分布式事务示例 - Saga 模式
class OrderSaga:
    def execute(self, order):
        # 步骤1:创建订单
        order = self.create_order(order)

        try:
            # 步骤2:扣减库存
            self.deduct_inventory(order.items)

            # 步骤3:处理支付
            self.process_payment(order)

        except Exception as e:
            # 补偿事务:回滚已执行的操作
            self.compensate(order)
            raise

3. 运维复杂度增加

需要引入更多基础设施:

  • 服务发现:Nacos、Consul、Eureka
  • 配置中心:Nacos、Apollo、Spring Cloud Config
  • API 网关:Kong、APISIX、Spring Cloud Gateway
  • 链路追踪:Jaeger、Zipkin、SkyWalking
  • 监控告警:Prometheus、Grafana
  • 日志聚合:ELK、Loki

4. 测试复杂度

# 契约测试示例
from pact import Consumer, Provider

pact = Consumer('OrderService').has_pact_with(Provider('PaymentService'))

# 定义契约
(pact
 .given('payment method exists')
 .upon_receiving('a payment request')
 .with_request('POST', '/payments', body={'amount': 100})
 .will_respond_with(200, body={'status': 'success'}))

def test_payment_integration():
    with pact:
        # 测试支付服务集成
        result = payment_client.pay(100)
        assert result['status'] == 'success'

1.4 从单体到微服务的演进策略

演进原则

  1. 渐进式拆分:不要一次性拆分所有服务
  2. 从边缘开始:先拆分非核心业务
  3. 按业务能力拆分:遵循领域驱动设计
  4. 保持向后兼容:确保系统持续可用

演进步骤

阶段1:单体架构
┌────────────────────────────────────┐
│           单体应用                  │
│  ┌──────┐ ┌──────┐ ┌──────┐       │
│  │ 用户 │ │ 订单 │ │ 支付 │       │
│  └──────┘ └──────┘ └──────┘       │
│           单一数据库                │
└────────────────────────────────────┘

阶段2:模块化单体
┌────────────────────────────────────┐
│           单体应用                  │
│  ┌──────────┐ ┌──────────┐        │
│  │ 用户模块  │ │ 订单模块  │        │
│  │──────────│ │──────────│        │
│  │ 用户服务  │ │ 订单服务  │        │
│  └──────────┘ └──────────┘        │
│           共享数据库                │
└────────────────────────────────────┘

阶段3:提取服务
┌─────────────┐  ┌─────────────────┐
│  用户服务    │  │    单体应用      │
│  用户数据库  │  │  订单 │ 支付     │
└─────────────┘  │    共享数据库    │
                 └─────────────────┘

阶段4:微服务架构
┌─────────────┐  ┌─────────────┐  ┌─────────────┐
│  用户服务    │  │  订单服务    │  │  支付服务    │
│  用户数据库  │  │  订单数据库  │  │  支付数据库  │
└─────────────┘  └─────────────┘  └─────────────┘

Strangler Fig 模式(绞杀者模式)

逐步用新服务替换旧系统:

# 路由层决定请求走向
class ServiceRouter:
    def route(self, request):
        if self.is_new_service_ready('user-service'):
            # 新服务处理
            return self.forward_to_new_service(request)
        else:
            # 旧系统处理
            return self.forward_to_legacy(request)

    def is_new_service_ready(self, service_name):
        # 检查新服务是否就绪
        # 可以逐步放开流量
        return self.traffic_percentage(service_name) > random.random()

1.5 何时选择微服务架构

适合微服务的场景

  1. 业务复杂度高:业务边界清晰,模块间耦合度低
  2. 团队规模大:多个团队并行开发
  3. 扩展需求多样:不同模块有不同的扩展需求
  4. 技术栈多样化:需要使用多种技术
  5. 高可用要求:需要故障隔离

不适合微服务的场景

  1. 初创公司:快速迭代,团队规模小
  2. 业务简单:业务逻辑不复杂
  3. 团队经验不足:缺乏微服务运维经验
  4. 性能敏感:无法接受分布式调用开销
  5. 预算有限:基础设施成本高

决策矩阵

因素 单体架构 微服务架构
团队规模 < 10 人 > 20 人
业务复杂度
部署频率
扩展需求 均匀 不均匀
运维能力 基础 成熟
预算 有限 充足

1.6 微服务架构最佳实践

1. 服务粒度控制

太粗:用户服务(包含用户、认证、权限、通知)
刚好:用户服务、认证服务、权限服务、通知服务
太细:用户创建服务、用户查询服务、用户更新服务

2. 服务命名规范

业务服务:user-service, order-service, payment-service
基础设施:api-gateway, config-server, service-registry

3. API 设计原则

# RESTful API 设计
GET    /api/v1/users          # 获取用户列表
GET    /api/v1/users/{id}     # 获取单个用户
POST   /api/v1/users          # 创建用户
PUT    /api/v1/users/{id}     # 更新用户
DELETE /api/v1/users/{id}     # 删除用户

4. 配置管理

# application.yaml
spring:
  application:
    name: user-service
  cloud:
    nacos:
      config:
        server-addr: nacos:8848
        namespace: production
        group: user-service

1.7 小结

本章介绍了微服务架构的核心概念、优势与挑战,以及从单体架构演进到微服务的策略。关键要点:

  1. 微服务架构适合复杂业务、大团队、高扩展需求的场景
  2. 微服务带来灵活性的同时也增加了系统复杂度
  3. 采用渐进式演进策略,不要一次性拆分
  4. 根据团队规模和业务复杂度选择合适的架构

思考题

  1. 你的项目当前处于什么阶段?是否适合微服务架构?
  2. 如果要拆分,你会从哪个业务模块开始?
  3. 你的团队是否具备微服务运维能力?

参考资料