微服务架构 microservices-architecture

微服务架构设计和实施指南,涵盖服务分解、通信模式、数据管理、部署策略和分布式系统的可观测性。

架构设计 0 次安装 0 次浏览 更新于 3/4/2026

name: 微服务架构 description: 设计和实现微服务架构,包括服务边界、通信模式、API网关、服务网格、服务发现和分布式系统模式。适用于构建微服务、分布式系统或面向服务的架构。

微服务架构

概览

全面的微服务架构设计、实施和维护指南。涵盖服务分解、通信模式、数据管理、部署策略和分布式系统的可观测性。

使用场景

  • 设计新的微服务架构
  • 将单体应用分解为微服务
  • 实现服务间通信
  • 设置API网关和服务网格
  • 实现服务发现
  • 管理分布式事务
  • 设计服务间数据一致性
  • 独立扩展服务

指南

1. 服务边界设计

领域驱动设计(DDD)方法

界限上下文:
┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐
│  订单服务  │  │  用户服务   │  │ 支付服务 │
│                 │  │                 │  │                 │
│ - 创建订单  │  │ - 用户档案  │  │ - 处理支付   │
│ - 订单状态  │  │ - 认证          │  │ - 退款        │
│ - 订单历史  │  │ - 偏好设置   │  │ - 交易       │
└─────────────────┘  └─────────────────┘  └─────────────────┘

分解策略:

  1. 按业务能力
电子商务系统:
- 产品目录服务
- 购物车服务
- 订单管理服务
- 支付服务
- 库存服务
- 运输服务
- 用户账户服务
  1. 按子域
医疗保健系统:
- 患者管理(核心域)
- 预约安排(核心域)
- 计费(支撑域)
- 通知(通用域)
- 报告(通用域)

服务设计示例

// order-service/src/domain/order.ts
export class OrderService {
  constructor(
    private orderRepository: OrderRepository,
    private eventBus: EventBus,
    private paymentClient: PaymentClient,
    private inventoryClient: InventoryClient
  ) {}

  async createOrder(request: CreateOrderRequest): Promise<Order> {
    // 1. 验证订单
    const order = Order.create(request);

    // 2. 检查库存(同步调用)
    const available = await this.inventoryClient.checkAvailability(
      order.items
    );
    if (!available) {
      throw new InsufficientInventoryError();
    }

    // 3. 保存订单
    await this.orderRepository.save(order);

    // 4. 发布事件(异步)
    await this.eventBus.publish(new OrderCreatedEvent(order));

    return order;
  }
}

2. 通信模式

同步通信(REST/gRPC)

REST API 示例:

// user-service/src/api/user.controller.ts
import express from 'express';

const router = express.Router();

// 获取用户档案
router.get('/users/:id', async (req, res) => {
  try {
    const user = await userService.findById(req.params.id);
    res.json(user);
  } catch (error) {
    if (error instanceof UserNotFoundError) {
      res.status(404).json({ error: '用户未找到' });
    } else {
      res.status(500).json({ error: '内部服务器错误' });
    }
  }
});

// 服务间调用,带有断路器
import axios from 'axios';
import CircuitBreaker from 'opossum';

const options = {
  timeout: 3000,
  errorThresholdPercentage: 50,
  resetTimeout: 30000
};

const breaker = new CircuitBreaker(
  async (userId: string) => {
    const response = await axios.get(
      `http://user-service/users/${userId}`,
      { timeout: 2000 }
    );
    return response.data;
  },
  options
);

breaker.fallback(() => ({ id: userId, name: '未知用户' }));

gRPC 示例:

// proto/user.proto
syntax = "proto3";

package user;

service UserService {
  rpc GetUser (GetUserRequest) returns (UserResponse);
  rpc ListUsers (ListUsersRequest) returns (stream UserResponse);
}

message GetUserRequest {
  string user_id = 1;
}

message UserResponse {
  string user_id = 1;
  string email = 2;
  string name = 3;
}
// 实现
import * as grpc from '@grpc/grpc-js';
import * as protoLoader from '@grpc/proto-loader';

const packageDefinition = protoLoader.loadSync('proto/user.proto');
const userProto = grpc.loadPackageDefinition(packageDefinition).user;

// 服务器
function getUser(call, callback) {
  const userId = call.request.user_id;
  const user = await userService.findById(userId);
  callback(null, user);
}

const server = new grpc.Server();
server.addService(userProto.UserService.service, { getUser });
server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure());

异步通信(消息队列)

基于事件的RabbitMQ:

// order-service/src/events/publisher.ts
import amqp from 'amqplib';

export class EventPublisher {
  private connection: amqp.Connection;
  private channel: amqp.Channel;

  async connect() {
    this.connection = await amqp.connect('amqp://localhost');
    this.channel = await this.connection.createChannel();
    await this.channel.assertExchange('orders', 'topic', { durable: true });
  }

  async publishOrderCreated(order: Order) {
    const event = {
      eventType: 'OrderCreated',
      timestamp: new Date(),
      data: order
    };

    this.channel.publish(
      'orders',
      'order.created',
      Buffer.from(JSON.stringify(event)),
      { persistent: true }
    );
  }
}

// inventory-service/src/events/consumer.ts
export class OrderEventConsumer {
  async subscribe() {
    const connection = await amqp.connect('amqp://localhost');
    const channel = await connection.createChannel();

    await channel.assertExchange('orders', 'topic', { durable: true });
    const q = await channel.assertQueue('inventory-order-events', {
      durable: true
    });

    await channel.bindQueue(q.queue, 'orders', 'order.created');

    channel.consume(q.queue, async (msg) => {
      if (msg) {
        const event = JSON.parse(msg.content.toString());
        await this.handleOrderCreated(event.data);
        channel.ack(msg);
      }
    });
  }

  private async handleOrderCreated(order: Order) {
    // 预留库存
    await inventoryService.reserveItems(order.items);
  }
}

Kafka事件流:

// event-streaming/kafka-producer.ts
import { Kafka } from 'kafkajs';

const kafka = new Kafka({
  clientId: 'order-service',
  brokers: ['kafka:9092']
});

const producer = kafka.producer();

export async function publishEvent(topic: string, event: any) {
  await producer.connect();
  await producer.send({
    topic,
    messages: [
      {
        key: event.aggregateId,
        value: JSON.stringify(event),
        headers: {
          'event-type': event.type,
          'correlation-id': event.correlationId
        }
      }
    ]
  });
}

// 消费者
const consumer = kafka.consumer({ groupId: 'inventory-service' });

await consumer.subscribe({ topic: 'order-events', fromBeginning: false });

await consumer.run({
  eachMessage: async ({ topic, partition, message }) => {
    const event = JSON.parse(message.value.toString());
    await eventHandler.handle(event);
  }
});

3. API网关模式

// api-gateway/src/gateway.ts
import express from 'express';
import httpProxy from 'http-proxy-middleware';
import jwt from 'jsonwebtoken';
import rateLimit from 'express-rate-limit';

const app = express();

// 速率限制
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15分钟
  max: 100
});

app.use(limiter);

// 认证中间件
const authenticateToken = (req, res, next) => {
  const token = req.headers['authorization']?.split(' ')[1];
  if (!token) return res.sendStatus(401);

  jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
    if (err) return res.sendStatus(403);
    req.user = user;
    next();
  });
};

// 路由到服务
app.use('/api/users', authenticateToken, httpProxy.createProxyMiddleware({
  target: 'http://user-service:3000',
  changeOrigin: true,
  pathRewrite: { '^/api/users': '/users' }
}));

app.use('/api/orders', authenticateToken, httpProxy.createProxyMiddleware({
  target: 'http://order-service:3000',
  changeOrigin: true,
  pathRewrite: { '^/api/orders': '/orders' }
}));

app.use('/api/products', httpProxy.createProxyMiddleware({
  target: 'http://product-service:3000',
  changeOrigin: true,
  pathRewrite: { '^/api/products': '/products' }
}));

// 聚合端点
app.get('/api/order-details/:orderId', authenticateToken, async (req, res) => {
  const orderId = req.params.orderId;

  // 并行请求多个服务
  const [order, user, products] = await Promise.all([
    fetch(`http://order-service:3000/orders/${orderId}`).then(r => r.json()),
    fetch(`http://user-service:3000/users/${req.user.id}`).then(r => r.json()),
    fetch(`http://product-service:3000/products?ids=${order.itemIds}`).then(r => r.json())
  ]);

  res.json({ order, user, products });
});

4. 服务发现

Consul示例

// service-registry/consul-client.ts
import Consul from 'consul';

export class ServiceRegistry {
  private consul: Consul.Consul;

  constructor() {
    this.consul = new Consul({
      host: 'consul',
      port: 8500
    });
  }

  // 注册服务
  async register(serviceName: string, servicePort: number) {
    await this.consul.agent.service.register({
      id: `${serviceName}-${process.env.HOSTNAME}`,
      name: serviceName,
      address: process.env.SERVICE_IP,
      port: servicePort,
      check: {
        http: `http://${process.env.SERVICE_IP}:${servicePort}/health`,
        interval: '10s',
        timeout: '5s'
      }
    });
  }

  // 发现服务
  async discover(serviceName: string): Promise<string> {
    const result = await this.consul.health.service({
      service: serviceName,
      passing: true
    });

    if (result.length === 0) {
      throw new Error(`服务 ${serviceName} 未找到`);
    }

    // 简单的轮询
    const service = result[Math.floor(Math.random() * result.length)];
    return `http://${service.Service.Address}:${service.Service.Port}`;
  }

  // 关闭时注销
  async deregister(serviceId: string) {
    await this.consul.agent.service.deregister(serviceId);
  }
}

Kubernetes服务发现

# user-service-deployment.yaml
apiVersion: v1
kind: Service
metadata:
  name: user-service
spec:
  selector:
    app: user-service
  ports:
    - protocol: TCP
      port: 80
      targetPort: 3000
  type: ClusterIP
---
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: user-service:latest
        ports:
        - containerPort: 3000
        env:
        - name: SERVICE_NAME
          value: "user-service"
// Kubernetes中的服务调用
const userServiceUrl = process.env.USER_SERVICE_URL || 'http://user-service';
const response = await fetch(`${userServiceUrl}/users/${userId}`);

5. 数据一致性模式

Saga模式(编排)

// order-saga-orchestrator.ts
export class OrderSagaOrchestrator {
  async createOrder(orderData: CreateOrderRequest) {
    const sagaId = uuidv4();
    const saga = new SagaInstance(sagaId);

    try {
      // 第1步:创建订单
      const order = await this.orderService.createOrder(orderData);
      saga.addCompensation(() => this.orderService.cancelOrder(order.id));

      // 第2步:预留库存
      await this.inventoryService.reserveItems(order.items);
      saga.addCompensation(() =>
        this.inventoryService.releaseReservation(order.id)
      );

      // 第3步:处理支付
      const payment = await this.paymentService.charge(order.total);
      saga.addCompensation(() =>
        this.paymentService.refund(payment.id)
      );

      // 第4步:确认订单
      await this.orderService.confirmOrder(order.id);

      return order;
    } catch (error) {
      // 反向补偿
      await saga.compensate();
      throw error;
    }
  }
}

事件溯源模式

// order-aggregate.ts
export class OrderAggregate {
  private id: string;
  private status: OrderStatus;
  private items: OrderItem[];
  private events: DomainEvent[] = [];

  // 命令处理器
  createOrder(command: CreateOrderCommand) {
    // 验证
    if (this.id) throw new Error('订单已存在');

    // 应用事件
    this.apply(new OrderCreatedEvent({
      orderId: command.orderId,
      userId: command.userId,
      items: command.items
    }));
  }

  // 事件处理器
  private apply(event: DomainEvent) {
    switch (event.type) {
      case 'OrderCreated':
        this.id = event.orderId;
        this.items = event.items;
        this.status = OrderStatus.PENDING;
        break;
      case 'OrderConfirmed':
        this.status = OrderStatus.CONFIRMED;
        break;
    }
    this.events.push(event);
  }

  getUncommittedEvents(): DomainEvent[] {
    return this.events;
  }
}

6. 服务网格(Istio)

# istio-config.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: order-service
spec:
  hosts:
  - order-service
  http:
  - match:
    - headers:
        user-type:
          exact: premium
    route:
    - destination:
        host: order-service
        subset: v2
      weight: 100
  - route:
    - destination:
        host: order-service
        subset: v1
      weight: 90
    - destination:
        host: order-service
        subset: v2
      weight: 10
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: order-service
spec:
  host: order-service
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 100
      http:
        http1MaxPendingRequests: 50
        maxRequestsPerConnection: 2
    outlierDetection:
      consecutiveErrors: 5
      interval: 30s
      baseEjectionTime: 30s
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

最佳实践

✅ DO

  • 围绕业务能力设计服务
  • 尽可能使用异步通信
  • 实现断路器以增强弹性
  • 使用API网关处理跨领域关注点
  • 实施分布式跟踪
  • 使用服务网格进行服务间通信
  • 为失败而设计(混沌工程)
  • 为所有服务实施健康检查
  • 使用相关ID进行请求跟踪
  • 版本化您的API
  • 实施适当的监控和警报
  • 使用事件驱动架构以实现松散耦合
  • 实施幂等操作
  • 使用数据库每服务模式

❌ DON’T

  • 在服务之间共享数据库
  • 创建过度细化的服务(纳米服务)
  • 使用分布式事务(两阶段提交)
  • 忽视网络延迟和故障
  • 在服务之间共享领域模型
  • 将所有服务作为一个单元部署
  • 硬编码服务URL
  • 忘记实施认证/授权
  • 对长时间运行的操作使用同步调用
  • 忽视向后兼容性
  • 跳过监控和日志记录
  • 创建服务之间的循环依赖

常见模式

模式1:前端后端(BFF)

// mobile-bff/src/api.ts - 针对移动设备优化
app.get('/api/home', async (req, res) => {
  const [featured, recommendations] = await Promise.all([
    productService.getFeatured(5),
    recommendationService.getForUser(req.user.id, 10)
  ]);
  res.json({ featured, recommendations });
});

// web-bff/src/api.ts - 为Web提供更多数据
app.get('/api/home', async (req, res) => {
  const [featured, recommendations, categories, promotions] = await Promise.all([
    productService.getFeatured(20),
    recommendationService.getForUser(req.user.id, 50),
    categoryService.getAll(),
    promotionService.getActive()
  ]);
  res.json({ featured, recommendations, categories, promotions });
});

模式2:边车模式

# 带有边车的Pod
apiVersion: v1
kind: Pod
metadata:
  name: app-with-sidecar
spec:
  containers:
  - name: app
    image: my-app:latest
  - name: logging-sidecar
    image: fluentd:latest
    volumeMounts:
    - name: logs
      mountPath: /logs
  volumes:
  - name: logs
    emptyDir: {}

工具和资源

  • 服务网格: Istio, Linkerd, Consul Connect
  • API网关: Kong, Apigee, AWS API Gateway
  • 服务发现: Consul, Eureka, Zookeeper
  • 消息队列: RabbitMQ, Apache Kafka, AWS SQS
  • 编排: Kubernetes, Docker Swarm, Nomad
  • 监控: Prometheus, Grafana, Datadog
  • 跟踪: Jaeger, Zipkin, AWS X-Ray
  • 断路器: Hystrix, Resilience4j, Polly