微服务架构 (Microservices)

微服务架构(Microservices Architecture)是一种将单体应用拆分为一组小型、独立服务的设计方法。每个服务运行在独立进程中,围绕业务能力构建,通过轻量级协议(通常是 HTTP/API)通信。1

单体架构 vs 微服务

单体架构 (Monolithic)

┌─────────────────────────────┐
│         单体应用             │
├─────────────────────────────┤
│  ┌─────┐  ┌─────┐  ┌─────┐ │
│  │ 用户 │  │ 订单 │  │ 库存 │ │
│  │ 模块 │  │ 模块 │  │ 模块 │ │
│  └──┬──┘  └──┬──┘  └──┬──┘ │
│     └────────┼────────┘    │
│              ▼              │
│         ┌──────┐           │
│         │数据库│           │
│         └──────┘           │
└─────────────────────────────┘

特点

  • 部署简单(单一部署单元)
  • 性能开销小(无网络调用)
  • 测试相对容易
  • 但扩展困难、维护成本高

微服务架构

┌─────────┐  ┌─────────┐  ┌─────────┐
│ 用户服务 │  │ 订单服务 │  │ 库存服务 │
│  :8001  │  │  :8002  │  │  :8003  │
└────┬────┘  └────┬────┘  └────┬────┘
     │            │            │
     └────────────┼────────────┘
                 ▼
          ┌────────────┐
          │   API Gateway │
          └────────────┘

特点

  • 每个服务独立部署
  • 按需扩展特定服务
  • 技术栈多样化
  • 故障隔离
  • 但复杂度高,运维挑战大

核心设计原则

1. 单一职责原则 (SRP)

每个微服务只负责一个业务领域:

用户服务 → 用户注册、登录、权限
订单服务 → 订单创建、查询、取消
支付服务 → 支付处理、退款
库存服务 → 库存查询、扣减

2. 独立数据存储

每个服务拥有自己的数据库:

用户服务 → 用户数据库 (MySQL)
订单服务 → 订单数据库 (PostgreSQL)
库存服务 → 库存数据库 (MongoDB)

好处

  • 服务间解耦
  • 可选择最适合的数据库
  • 独立扩展

3. API 优先设计

服务间通过明确定义的 API 通信:

# OpenAPI 规范示例
openapi: 3.0.0
info:
  title: Order Service API
  version: 1.0.0
paths:
  /orders:
    post:
      summary: 创建订单
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Order'
      responses:
        '201':
          description: 订单创建成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrderResponse'

服务间通信

同步通信 (Synchronous)

REST/gHTTP

# 获取用户信息
curl -X GET http://user-service:8001/users/123

gRPC

// user.proto
service UserService {
    rpc GetUser(GetUserRequest) returns (User);
    rpc ListUsers(ListUsersRequest) returns (ListUsersResponse);
}
 
message GetUserRequest {
    string user_id = 1;
}
 
message User {
    string id = 1;
    string name = 2;
    string email = 3;
}

异步通信 (Asynchronous)

消息队列

订单服务 ──publish──► 消息队列 ──subscribe──► 库存服务
                               │
                               └──subscribe──► 通知服务

常用消息队列:

  • RabbitMQ:可靠性高,功能丰富
  • Apache Kafka:高吞吐量,日志处理
  • ActiveMQ:Java 生态系统
# RabbitMQ 配置示例
# docker-compose.yml
services:
  rabbitmq:
    image: rabbitmq:3-management
    ports:
      - "5672:5672"
      - "15672:15672"

事件驱动 (Event-Driven)

服务通过事件进行通信:

// 订单创建事件
{
    "event_type": "order_created",
    "order_id": "ORD-2024-001",
    "user_id": "USR-123",
    "items": [
        {"product_id": "PROD-456", "quantity": 2}
    ],
    "timestamp": "2024-01-15T10:30:00Z"
}

API 网关 (API Gateway)

API 网关作为系统的单一入口:

                    ┌──────────────┐
    客户端 ─────────►│  API Gateway  │
                    └──────┬───────┘
                           │
         ┌─────────────────┼─────────────────┐
         ▼                 ▼                 ▼
   ┌──────────┐      ┌──────────┐      ┌──────────┐
   │用户服务   │      │订单服务   │      │商品服务   │
   └──────────┘      └──────────┘      └──────────┘

功能

  • 请求路由
  • 身份认证/鉴权
  • 限流熔断
  • 日志监控
  • 协议转换

常用 API 网关

网关特点
Nginx高性能,反向代理
Kong可扩展,插件丰富
Spring Cloud GatewayJava 生态,Spring 集成
Envoy服务网格数据平面

服务发现 (Service Discovery)

客户端发现

服务直接向注册中心查询:

# Python 服务发现客户端
import consul
 
c = consul.Consul()
 
def get_user_service():
    services = c.agent.services()
    user_service = services.get('user-service')
    if user_service:
        return f"http://{user_service['Address']}:{user_service['Port']}"
    return None

服务端发现

通过负载均衡器发现服务:

服务 ──查询──► 负载均衡器 ──转发──► 目标服务

熔断器模式 (Circuit Breaker)

防止级联故障:

import time
from functools import wraps
 
class CircuitBreaker:
    def __init__(self, failure_threshold=5, timeout=60):
        self.failure_threshold = failure_threshold
        self.timeout = timeout
        self.failures = 0
        self.last_failure_time = None
        self.state = 'CLOSED'  # CLOSED, OPEN, HALF_OPEN
    
    def call(self, func, *args, **kwargs):
        if self.state == 'OPEN':
            if time.time() - self.last_failure_time > self.timeout:
                self.state = 'HALF_OPEN'
            else:
                raise CircuitOpenError("Circuit is OPEN")
        
        try:
            result = func(*args, **kwargs)
            if self.state == 'HALF_OPEN':
                self.state = 'CLOSED'
                self.failures = 0
            return result
        except Exception as e:
            self.failures += 1
            self.last_failure_time = time.time()
            if self.failures >= self.failure_threshold:
                self.state = 'OPEN'
            raise

分布式事务

微服务架构中,跨服务的事务处理是难点。

两阶段提交 (2PC)

第一阶段(Prepare):
协调者 ──prepare──► 所有参与者
              ◄──OK/FAIL──

第二阶段(Commit/Rollback):
协调者 ──commit──► 所有参与者(全部OK)
              ◄──ACK──

Saga 模式

将大事务拆分为多个小事务,通过补偿机制保证最终一致性:

创建订单 Saga:
1. 创建订单(pending) ──► 成功
2. 预留库存(reserved) ◄──► 失败则释放
3. 扣款(paid)         ◄──► 失败则释放库存
4. 完成订单(completed)

补偿动作

def cancel_order(order_id):
    # 1. 取消订单
    order_service.cancel(order_id)
    # 2. 释放库存
    inventory_service.release(order_id)
    # 3. 退款
    payment_service.refund(order_id)

容器化与编排

Docker 部署

# user-service/Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8001
CMD ["python", "app.py"]

Docker Compose 本地开发

# docker-compose.yml
version: '3.8'
services:
  user-service:
    build: ./user-service
    ports:
      - "8001:8001"
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/users
    depends_on:
      - db
  
  order-service:
    build: ./order-service
    ports:
      - "8002:8002"
    environment:
      - USER_SERVICE_URL=http://user-service:8001
      - DATABASE_URL=postgresql://user:pass@db:5432/orders
  
  api-gateway:
    build: ./api-gateway
    ports:
      - "80:8080"
    depends_on:
      - user-service
      - order-service
  
  db:
    image: postgres:15
    volumes:
      - postgres_data:/var/lib/postgresql/data
 
volumes:
  postgres_data:

Kubernetes 部署

# user-service-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: user-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: user-service
  template:
    metadata:
      labels:
        app: user-service
    spec:
      containers:
      - name: user-service
        image: myregistry/user-service:v1.0
        ports:
        - containerPort: 8001
        resources:
          limits:
            memory: "256Mi"
            cpu: "500m"
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: db-credentials
              key: url
---
apiVersion: v1
kind: Service
metadata:
  name: user-service
spec:
  selector:
    app: user-service
  ports:
  - port: 80
    targetPort: 8001
  type: ClusterIP

监控与日志

分布式追踪

使用 Jaeger 或 Zipkin:

请求: GET /orders/123
  │
  ▼
API Gateway (10ms)
  │
  ▼
Order Service (50ms)
  ├── User Service (20ms)
  └── Inventory Service (15ms)

日志聚合

使用 ELK Stack (Elasticsearch, Logstash, Kibana):

各服务 ──► Filebeat ──► Logstash ──► Elasticsearch ──► Kibana
                     └────────────┐
                                  ▼
                              Loki/Grafana

关键指标

指标类型示例
RED 指标Rate(请求率)、Errors(错误率)、Duration(延迟)
基础设施CPU、内存、网络
业务指标订单量、转化率

优缺点总结

优点

  1. 独立部署:可单独部署每个服务
  2. 技术多样性:不同服务可用不同技术栈
  3. 故障隔离:一个服务故障不导致全线崩溃
  4. 团队自治:团队可独立负责特定服务
  5. 按需扩展:只扩展需要的服务

缺点

  1. 复杂度高:分布式系统的固有复杂性
  2. 运维挑战:需要成熟的 CI/CD 和监控
  3. 数据一致性:跨服务事务处理困难
  4. 网络延迟:服务调用有额外开销
  5. 测试复杂:集成测试比单体复杂

适用场景

适合微服务

  • 大型复杂应用
  • 需要高扩展性
  • 多团队协作开发
  • 快速迭代需求

可能不需要微服务

  • 小型简单应用
  • 团队规模小
  • 创业初期快速验证
  • 运维能力有限

参考

Footnotes

  1. 本段参考微服务架构 - OI Wiki